Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/shiny-suits-pick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@seed-design/rootage-artifacts": patch
"@seed-design/css": patch
---

NotificationBadge의 size=large variant가 최소 너비를 갖도록 하고, 폰트 스케일링 배율이 1보다 큰 환경에서도 항상 최소 1/1 비율을 유지하도록 업데이트합니다.
26 changes: 23 additions & 3 deletions docs/public/rootage/components/notification-badge.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,17 @@
"color": {
"type": "color"
},
"minWidth": {
"type": "dimension",
"description": "낮은 폰트 스케일링 배율에서 최소 크기를 보장하고, 높은 폰트 스케일링 배율에서 레이블이 좁은 너비를 차지할 때도 정사각형 비율을 보장하기 위해 minWidth, minHeight, minAspectRatio를 동시에 만족시켜야 합니다."
},
"minHeight": {
"type": "dimension"
"type": "dimension",
"description": "낮은 폰트 스케일링 배율에서 최소 크기를 보장하고, 높은 폰트 스케일링 배율에서 레이블이 좁은 너비를 차지할 때도 정사각형 비율을 보장하기 위해 minWidth, minHeight, minAspectRatio를 동시에 만족시켜야 합니다."
},
"minAspectRatio": {
"type": "number",
"description": "낮은 폰트 스케일링 배율에서 최소 크기를 보장하고, 높은 폰트 스케일링 배율에서 레이블이 좁은 너비를 차지할 때도 정사각형 비율을 보장하기 위해 minWidth, minHeight, minAspectRatio를 동시에 만족시켜야 합니다."
},
"paddingX": {
"type": "dimension"
Expand Down Expand Up @@ -61,10 +70,10 @@
"size": {
"values": {
"large": {
"description": "라벨을 포함해 구체적인 알림 수나 상태 정보를 제공합니다."
"description": "라벨을 포함해 구체적인 알림 수나 상태 정보를 제공합니다. 세부 정보가 중요하고 충분한 공간이 있을 때 사용합니다. 내부 라벨을 반드시 포함해야 합니다."
},
"small": {
"description": "간결한 도트 형태로, 텍스트 없이 상태 변화만 표시합니다."
"description": "간결한 도트 형태로, 텍스트 없이 상태 변화만 표시합니다. 알림의 존재 여부만 중요하거나 공간이 제한된 경우에 적합합니다. 내부 라벨은 지원하지 않습니다."
}
},
"defaultValue": "large"
Expand Down Expand Up @@ -107,13 +116,24 @@
],
"slots": {
"root": {
"minWidth": {
"type": "dimension",
"value": {
"value": 18,
"unit": "px"
}
},
"minHeight": {
"type": "dimension",
"value": {
"value": 18,
"unit": "px"
}
},
"minAspectRatio": {
"type": "number",
"value": 1
},
"paddingX": {
"type": "dimension",
"value": "$dimension.x1"
Expand Down
95 changes: 95 additions & 0 deletions docs/stories/NotificationBadge.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import type { Meta, StoryObj } from "@storybook/nextjs";

import {
Box,
HStack,
Icon,
NotificationBadge,
NotificationBadgePositioner,
Text,
VStack,
} from "@seed-design/react";

import type { NotificationBadgePositionerVariantProps } from "@seed-design/css/recipes/notification-badge-positioner";
import { createStoryWithParameters } from "@/stories/utils/parameters";
import { SeedThemeDecorator } from "./components/decorator";
import { VariantTable } from "./components/variant-table";
import { IconBellLine } from "@karrotmarket/react-monochrome-icon";

const meta = {
component: NotificationBadge,
decorators: [SeedThemeDecorator],
} satisfies Meta<typeof NotificationBadge>;

export default meta;

type Story = StoryObj<typeof meta>;

type NotificationBadgeCase = {
caseLabel: string;
attach: NonNullable<NotificationBadgePositionerVariantProps["attach"]>;
size: NonNullable<NotificationBadgePositionerVariantProps["size"]>;
label?: string;
};

const CASES: NotificationBadgeCase[] = [
{ caseLabel: "icon / small (dot)", attach: "icon", size: "small" },
{ caseLabel: "icon / large (1 digit)", attach: "icon", size: "large", label: "1" },
{ caseLabel: "icon / large (2 digits)", attach: "icon", size: "large", label: "12" },
{ caseLabel: "icon / large (overflow)", attach: "icon", size: "large", label: "99+" },
{ caseLabel: "text / small (dot)", attach: "text", size: "small" },
];

const conditionMap = {
caseLabel: CASES.reduce(
(acc, item) => {
acc[item.caseLabel] = item;

return acc;
},
{} as Record<string, NotificationBadgeCase>,
),
};

const IconAnchor = () => <Icon svg={<IconBellLine />} color="fg.neutral" />;

const TextAnchor = () => <Text color="fg.neutral">Inbox</Text>;

const NotificationBadgeCase = ({ attach, size, label }: NotificationBadgeCase) => {
return (
<Box as="span" display="inline-flex" position="relative">
{attach === "text" ? <TextAnchor /> : <IconAnchor />}
<NotificationBadgePositioner attach={attach} size={size}>
{size === "large" ? <NotificationBadge>{label}</NotificationBadge> : <NotificationBadge />}
</NotificationBadgePositioner>
</Box>
);
};

const CommonStoryTemplate: Story = {
render: (args) => (
<VariantTable
Component={NotificationBadgeCase}
variantMap={{}}
conditionMap={conditionMap}
{...args}
/>
),
};

export const LightTheme = CommonStoryTemplate;

export const DarkTheme = createStoryWithParameters({
...CommonStoryTemplate,
parameters: { theme: "dark" },
});

export const FontScalingExtraSmall = createStoryWithParameters({
...CommonStoryTemplate,
parameters: { fontScale: "Extra Small" },
});

export const FontScalingExtraExtraExtraLarge = createStoryWithParameters({
...CommonStoryTemplate,
parameters: { fontScale: "Extra Extra Extra Large" },
});
1 change: 1 addition & 0 deletions packages/css/all.css
Original file line number Diff line number Diff line change
Expand Up @@ -6203,6 +6203,7 @@
}

.seed-notification-badge--size_large {
min-width: max(18px, calc(var(--seed-line-height-t1) + 0px * 2));
border-radius: var(--seed-radius-full);
min-height: 18px;
padding-left: var(--seed-dimension-x1);
Expand Down
1 change: 1 addition & 0 deletions packages/css/all.layered.css
Original file line number Diff line number Diff line change
Expand Up @@ -6304,6 +6304,7 @@
}

.seed-notification-badge--size_large {
min-width: max(18px, calc(var(--seed-line-height-t1) + 0px * 2));
border-radius: var(--seed-radius-full);
min-height: 18px;
padding-left: var(--seed-dimension-x1);
Expand Down
2 changes: 1 addition & 1 deletion packages/css/all.layered.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/css/all.min.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/css/recipes/notification-badge.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
border-radius: var(--seed-radius-full)
}
.seed-notification-badge--size_large {
min-width: max(18px, calc(var(--seed-line-height-t1) + 0px * 2));
min-height: 18px;
border-radius: var(--seed-radius-full);
padding-left: var(--seed-dimension-x1);
Expand Down
1 change: 1 addition & 0 deletions packages/css/recipes/notification-badge.layered.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
}

.seed-notification-badge--size_large {
min-width: max(18px, calc(var(--seed-line-height-t1) + 0px * 2));
border-radius: var(--seed-radius-full);
min-height: 18px;
padding-left: var(--seed-dimension-x1);
Expand Down
9 changes: 7 additions & 2 deletions packages/css/vars/component/notification-badge.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@ export declare const vars: {
}
},
/**
* 라벨을 포함해 구체적인 알림 수나 상태 정보를 제공합니다.
* 라벨을 포함해 구체적인 알림 수나 상태 정보를 제공합니다. 세부 정보가 중요하고 충분한 공간이 있을 때 사용합니다. 내부 라벨을 반드시 포함해야 합니다.
*/
"sizeLarge": {
"enabled": {
"root": {
/** 낮은 폰트 스케일링 배율에서 최소 크기를 보장하고, 높은 폰트 스케일링 배율에서 레이블이 좁은 너비를 차지할 때도 정사각형 비율을 보장하기 위해 minWidth, minHeight, minAspectRatio를 동시에 만족시켜야 합니다. */
"minWidth": "18px",
/** 낮은 폰트 스케일링 배율에서 최소 크기를 보장하고, 높은 폰트 스케일링 배율에서 레이블이 좁은 너비를 차지할 때도 정사각형 비율을 보장하기 위해 minWidth, minHeight, minAspectRatio를 동시에 만족시켜야 합니다. */
"minHeight": "18px",
/** 낮은 폰트 스케일링 배율에서 최소 크기를 보장하고, 높은 폰트 스케일링 배율에서 레이블이 좁은 너비를 차지할 때도 정사각형 비율을 보장하기 위해 minWidth, minHeight, minAspectRatio를 동시에 만족시켜야 합니다. */
"minAspectRatio": "1",
"paddingX": "var(--seed-dimension-x1)",
"paddingY": "0px",
"cornerRadius": "var(--seed-radius-full)",
Expand All @@ -31,7 +36,7 @@ export declare const vars: {
}
},
/**
* 간결한 도트 형태로, 텍스트 없이 상태 변화만 표시합니다.
* 간결한 도트 형태로, 텍스트 없이 상태 변화만 표시합니다. 알림의 존재 여부만 중요하거나 공간이 제한된 경우에 적합합니다. 내부 라벨은 지원하지 않습니다.
*/
"sizeSmall": {
"enabled": {
Expand Down
2 changes: 2 additions & 0 deletions packages/css/vars/component/notification-badge.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ export const vars = {
"sizeLarge": {
"enabled": {
"root": {
"minWidth": "18px",
"minHeight": "18px",
"minAspectRatio": "1",
"paddingX": "var(--seed-dimension-x1)",
"paddingY": "0px",
"cornerRadius": "var(--seed-radius-full)",
Expand Down
2 changes: 2 additions & 0 deletions packages/qvism-preset/src/recipes/notification-badge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ export const notificationBadge = defineRecipe({
borderRadius: vars.sizeSmall.enabled.root.cornerRadius,
},
large: {
// we do this rather than consuming vars.sizeLarge.enabled.root.minAspectRatio because we can't have such nice things in CSS yet
minWidth: `max(${vars.sizeLarge.enabled.root.minWidth}, calc(${vars.sizeLarge.enabled.label.lineHeight} + ${vars.sizeLarge.enabled.root.paddingY} * 2))`,
minHeight: vars.sizeLarge.enabled.root.minHeight,
borderRadius: vars.sizeLarge.enabled.root.cornerRadius,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@ export declare const vars: {
}
},
/**
* 라벨을 포함해 구체적인 알림 수나 상태 정보를 제공합니다.
* 라벨을 포함해 구체적인 알림 수나 상태 정보를 제공합니다. 세부 정보가 중요하고 충분한 공간이 있을 때 사용합니다. 내부 라벨을 반드시 포함해야 합니다.
*/
"sizeLarge": {
"enabled": {
"root": {
/** 낮은 폰트 스케일링 배율에서 최소 크기를 보장하고, 높은 폰트 스케일링 배율에서 레이블이 좁은 너비를 차지할 때도 정사각형 비율을 보장하기 위해 minWidth, minHeight, minAspectRatio를 동시에 만족시켜야 합니다. */
"minWidth": "18px",
/** 낮은 폰트 스케일링 배율에서 최소 크기를 보장하고, 높은 폰트 스케일링 배율에서 레이블이 좁은 너비를 차지할 때도 정사각형 비율을 보장하기 위해 minWidth, minHeight, minAspectRatio를 동시에 만족시켜야 합니다. */
"minHeight": "18px",
/** 낮은 폰트 스케일링 배율에서 최소 크기를 보장하고, 높은 폰트 스케일링 배율에서 레이블이 좁은 너비를 차지할 때도 정사각형 비율을 보장하기 위해 minWidth, minHeight, minAspectRatio를 동시에 만족시켜야 합니다. */
"minAspectRatio": "1",
"paddingX": "var(--seed-dimension-x1)",
"paddingY": "0px",
"cornerRadius": "var(--seed-radius-full)",
Expand All @@ -31,7 +36,7 @@ export declare const vars: {
}
},
/**
* 간결한 도트 형태로, 텍스트 없이 상태 변화만 표시합니다.
* 간결한 도트 형태로, 텍스트 없이 상태 변화만 표시합니다. 알림의 존재 여부만 중요하거나 공간이 제한된 경우에 적합합니다. 내부 라벨은 지원하지 않습니다.
*/
"sizeSmall": {
"enabled": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ export const vars = {
"sizeLarge": {
"enabled": {
"root": {
"minWidth": "18px",
"minHeight": "18px",
"minAspectRatio": "1",
"paddingX": "var(--seed-dimension-x1)",
"paddingY": "0px",
"cornerRadius": "var(--seed-radius-full)",
Expand Down
21 changes: 19 additions & 2 deletions packages/rootage/components/notification-badge.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,21 @@ data:
properties:
color:
type: color
minWidth:
type: dimension
description: 낮은 폰트 스케일링 배율에서 최소 크기를 보장하고, 높은 폰트 스케일링 배율에서 레이블이 좁은 너비를 차지할 때도
정사각형 비율을 보장하기 위해 minWidth, minHeight, minAspectRatio를 동시에 만족시켜야
합니다.
minHeight:
type: dimension
description: 낮은 폰트 스케일링 배율에서 최소 크기를 보장하고, 높은 폰트 스케일링 배율에서 레이블이 좁은 너비를 차지할 때도
정사각형 비율을 보장하기 위해 minWidth, minHeight, minAspectRatio를 동시에 만족시켜야
합니다.
minAspectRatio:
type: number
description: 낮은 폰트 스케일링 배율에서 최소 크기를 보장하고, 높은 폰트 스케일링 배율에서 레이블이 좁은 너비를 차지할 때도
정사각형 비율을 보장하기 위해 minWidth, minHeight, minAspectRatio를 동시에 만족시켜야
합니다.
paddingX:
type: dimension
paddingY:
Expand Down Expand Up @@ -40,9 +53,11 @@ data:
size:
values:
large:
description: 라벨을 포함해 구체적인 알림 수나 상태 정보를 제공합니다.
description: 라벨을 포함해 구체적인 알림 수나 상태 정보를 제공합니다. 세부 정보가 중요하고 충분한 공간이 있을 때 사용합니다. 내부
라벨을 반드시 포함해야 합니다.
small:
description: 간결한 도트 형태로, 텍스트 없이 상태 변화만 표시합니다.
description: 간결한 도트 형태로, 텍스트 없이 상태 변화만 표시합니다. 알림의 존재 여부만 중요하거나 공간이 제한된 경우에
적합합니다. 내부 라벨은 지원하지 않습니다.
definitions:
base:
enabled:
Expand All @@ -53,7 +68,9 @@ data:
size=large:
enabled:
root:
minWidth: 18px
minHeight: 18px
minAspectRatio: 1
paddingX: $dimension.x1
paddingY: 0px
cornerRadius: $radius.full
Expand Down
Loading