Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
81 changes: 81 additions & 0 deletions docs/stories/NotificationBadge.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type { Meta, StoryObj } from "@storybook/nextjs";

import {
Box,
Icon,
NotificationBadge,
NotificationBadgePositioner,
Text,
} 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>;

interface Case {
attach: NonNullable<NotificationBadgePositionerVariantProps["attach"]>;
size: NonNullable<NotificationBadgePositionerVariantProps["size"]>;
label?: string;
}

const conditionMap = {
case: {
"icon / small (dot)": { attach: "icon", size: "small" },
"icon / large (1 digit)": { attach: "icon", size: "large", label: "1" },
"icon / large (2 digits)": { attach: "icon", size: "large", label: "12" },
"icon / large (overflow)": { attach: "icon", size: "large", label: "99+" },
"text / small (dot)": { attach: "text", size: "small" },
},
};

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

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

const NotificationBadgeCase = ({ attach, size, label }: Case) => (
<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