@ponti-studios/ui 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/index.js +70 -112
  2. package/dist/index.js.map +1 -1
  3. package/package.json +25 -23
  4. package/src/animations.css +92 -15
  5. package/src/components/data-display/accordion.tsx +15 -6
  6. package/src/components/data-display/filter-chip.stories.tsx +38 -0
  7. package/src/components/data-display/filter-chip.tsx +9 -3
  8. package/src/components/data-display/sort-controls.tsx +1 -1
  9. package/src/components/data-display/table.tsx +3 -7
  10. package/src/components/feedback/empty-state.tsx +16 -6
  11. package/src/components/feedback/file-upload-status-badge.tsx +1 -1
  12. package/src/components/feedback/progress.tsx +2 -2
  13. package/src/components/feedback/update-guard.tsx +1 -1
  14. package/src/components/forms/calendar.tsx +6 -3
  15. package/src/components/forms/field.tsx +3 -3
  16. package/src/components/forms/input.tsx +1 -1
  17. package/src/components/forms/passkey-management.tsx +2 -2
  18. package/src/components/forms/radio-group.tsx +1 -1
  19. package/src/components/forms/select.tsx +11 -4
  20. package/src/components/forms/slider.tsx +16 -4
  21. package/src/components/forms/stepper.tsx +1 -1
  22. package/src/components/forms/textarea.tsx +1 -1
  23. package/src/components/layout/section-intro.tsx +1 -1
  24. package/src/components/navigation/app-navigation.tsx +4 -4
  25. package/src/components/navigation/pagination-controls.tsx +2 -2
  26. package/src/components/navigation/tabs.tsx +1 -1
  27. package/src/components/overlays/alert-dialog.tsx +30 -8
  28. package/src/components/overlays/command.tsx +123 -20
  29. package/src/components/overlays/dialog.tsx +4 -4
  30. package/src/components/overlays/dropdown-menu.tsx +137 -21
  31. package/src/components/overlays/popover.tsx +14 -3
  32. package/src/components/overlays/sheet.tsx +24 -8
  33. package/src/components/primitives/avatar.tsx +6 -2
  34. package/src/components/primitives/badge.tsx +5 -2
  35. package/src/components/primitives/button.tsx +16 -18
  36. package/src/components/primitives/card.stories.tsx +2 -2
  37. package/src/components/primitives/card.tsx +2 -5
  38. package/src/constants/chart-colors.ts +2 -2
  39. package/src/styles.css +153 -63
  40. package/src/tokens/chart-colors.stories.tsx +192 -0
  41. package/src/tokens/color-systems.stories.tsx +21 -3
  42. package/src/tokens/foundations.stories.tsx +66 -16
  43. package/src/tokens/generated/dark.colors.generated.ts +23 -50
  44. package/src/tokens/generated/dark.css +23 -48
  45. package/src/tokens/generated/foundations.css +2 -2
  46. package/src/tokens/generated/foundations.generated.ts +14 -6
  47. package/src/tokens/generated/light.colors.generated.ts +23 -50
  48. package/src/tokens/generated/light.css +23 -48
  49. package/src/tokens/index.ts +14 -9
  50. package/src/tokens/layout.stories.tsx +40 -3
@@ -3,52 +3,27 @@
3
3
  */
4
4
 
5
5
  :root {
6
- --color-surface-canvas: #ffffff;
7
- --color-surface-panel: #f8f8f8;
8
- --color-surface-raised: #ffffff;
9
- --color-surface-inset: #ffffff;
10
- --color-surface-hover: #e9e9e9;
11
- --color-surface-pressed: #505050;
12
- --color-surface-selected: #e5f0fe;
13
- --color-surface-disabled: #e9e9e9;
14
- --color-overlay-scrim: #000000;
15
- --color-text-primary: #131313;
16
- --color-text-secondary: #505050;
17
- --color-text-tertiary: #717171;
18
- --color-text-disabled: #8f8f8f;
19
- --color-text-accent: #3b63fb;
20
- --color-text-destructive: #d73220;
21
- --color-text-success: #079355;
22
- --color-text-warning: #d45b00;
23
- --color-text-on-accent: #ffffff;
24
- --color-text-on-destructive: #ffffff;
25
- --color-text-on-success: #ffffff;
26
- --color-text-on-warning: #000000;
27
- --color-border-subtle: #dadada;
28
- --color-border-default: #c6c6c6;
29
- --color-border-strong: #8f8f8f;
30
- --color-border-focus: #4b75ff;
31
- --color-border-accent: #3b63fb;
32
- --color-border-destructive: #d73220;
33
- --color-accent: #3b63fb;
34
- --color-accent-hover: #274dea;
35
- --color-accent-pressed: #274dea;
36
- --color-accent-subtle: #e5f0fe;
37
- --color-destructive: #d73220;
38
- --color-destructive-hover: #b72818;
39
- --color-destructive-pressed: #b72818;
40
- --color-destructive-subtle: #ffebe8;
41
- --color-success: #05834e;
42
- --color-success-subtle: #d7f7e1;
43
- --color-warning: #fc7d00;
44
- --color-warning-subtle: #ffeccf;
45
- --color-ring-focus: #4b75ff;
46
- --color-chart-1: #4b75ff;
47
- --color-chart-2: #079355;
48
- --color-chart-3: #4b75ff;
49
- --color-chart-4: #d45b00;
50
- --color-chart-5: #8f8f8f;
51
- --color-chart-positive: #079355;
52
- --color-chart-negative: #f03823;
53
- --color-chart-neutral: #8f8f8f;
6
+ --background: #fcfcfd;
7
+ --card: #f9f9fb;
8
+ --popover: #f0f0f3;
9
+ --muted: #f9f9fb;
10
+ --text-primary: #1c2024;
11
+ --text-secondary: #60646c;
12
+ --tertiary: #80838d;
13
+ --primary: #3e63dd;
14
+ --destructive: #e5484d;
15
+ --success: #30a46c;
16
+ --warning: #ffc53d;
17
+ --primary-foreground: #ffffff;
18
+ --destructive-foreground: #ffffff;
19
+ --border-default: #cdced6;
20
+ --focus-ring: #3e63dd;
21
+ --chart-1: #3e63dd;
22
+ --chart-2: #6e56cf;
23
+ --chart-3: #12a594;
24
+ --chart-4: #f76b15;
25
+ --chart-5: #8b8d98;
26
+ --chart-positive: #30a46c;
27
+ --chart-negative: #e5484d;
28
+ --chart-neutral: #b9bbc6;
54
29
  }
@@ -13,28 +13,33 @@ const toBezier = (value: number[]) => `cubic-bezier(${value.join(", ")})`;
13
13
  type NormalizedSpacingKey<Key extends string> = Key extends `${infer Whole}-${infer Fraction}`
14
14
  ? `${Whole}.${Fraction}`
15
15
  : Key;
16
- export type SpacingToken = NormalizedSpacingKey<keyof typeof foundations["spacing-scale"] & string>;
16
+ export type SpacingToken = NormalizedSpacingKey<
17
+ keyof (typeof foundations)["spacing-scale"] & string
18
+ >;
17
19
 
18
- export const colorTokenNames = Object.keys(lightTokens.color) as Array<keyof typeof lightTokens.color>;
19
- export type ColorToken = keyof typeof lightTokens.color;
20
+ export const colorTokenNames = Object.keys(lightTokens) as Array<keyof typeof lightTokens>;
21
+ export type ColorToken = keyof typeof lightTokens;
20
22
  export type ColorMode = "light" | "dark";
21
23
  export type ColorTheme = Readonly<Record<ColorToken, string>>;
22
24
 
23
25
  export const colorThemes = {
24
- light: lightTokens.color,
25
- dark: darkTokens.color,
26
+ light: lightTokens,
27
+ dark: darkTokens,
26
28
  } as const satisfies Record<ColorMode, ColorTheme>;
27
29
 
28
30
  export const colors = colorTokenNames.reduce(
29
31
  (accumulator, token) => {
30
- accumulator[token] = `var(--color-${token})`;
32
+ accumulator[token] = `var(--${token})`;
31
33
  return accumulator;
32
34
  },
33
- {} as Record<ColorToken, `var(--color-${string})`>,
35
+ {} as Record<ColorToken, `var(--${string})`>,
34
36
  );
35
37
 
36
38
  export const spacing = Object.fromEntries(
37
- Object.entries(foundations["spacing-scale"]).map(([key, value]) => [key.replace("-", "."), toPixels(value)]),
39
+ Object.entries(foundations["spacing-scale"]).map(([key, value]) => [
40
+ key.replace("-", "."),
41
+ toPixels(value),
42
+ ]),
38
43
  ) as Record<SpacingToken, number>;
39
44
 
40
45
  export const fontFamilies = Object.fromEntries(
@@ -48,7 +53,7 @@ export const textSizes = Object.fromEntries(
48
53
  export const textLineHeights = foundations["text-line-height"];
49
54
  export const fontWeights = Object.fromEntries(
50
55
  Object.entries(foundations["font-weight"]).map(([key, value]) => [key, String(value)]),
51
- ) as Record<keyof typeof foundations["font-weight"], string>;
56
+ ) as Record<keyof (typeof foundations)["font-weight"], string>;
52
57
  export const tracking = foundations.tracking;
53
58
  export const leading = foundations.leading;
54
59
  export const radii = Object.fromEntries(
@@ -1,13 +1,50 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react-vite";
2
2
 
3
- const meta = { title: "Foundations/Layout Rhythm", parameters: { layout: "fullscreen" } } satisfies Meta;
3
+ const meta = {
4
+ title: "Foundations/Layout Rhythm",
5
+ parameters: { layout: "fullscreen" },
6
+ } satisfies Meta;
4
7
  export default meta;
5
8
  type Story = StoryObj<typeof meta>;
6
9
 
7
10
  export const PageShell: Story = {
8
- render: () => <main className="page-shell bg-background text-foreground"><header className="flex flex-col gap-4"><p className="text-sm text-muted-foreground">Page shell</p><h1 className="text-4xl font-semibold tracking-tight">A consistent starting point for content pages.</h1></header><section className="flex flex-col gap-4"><h2 className="text-2xl font-semibold">Section rhythm</h2><p className="max-w-2xl text-base text-muted-foreground">Layout helpers compose standard Tailwind spacing and semantic colors.</p></section></main>,
11
+ render: () => (
12
+ <main className="page-shell bg-background text-foreground">
13
+ <header className="flex flex-col gap-4">
14
+ <p className="text-muted-foreground text-sm">Page shell</p>
15
+ <h1 className="text-4xl font-semibold tracking-tight">
16
+ A consistent starting point for content pages.
17
+ </h1>
18
+ </header>
19
+ <section className="flex flex-col gap-4">
20
+ <h2 className="text-2xl font-semibold">Section rhythm</h2>
21
+ <p className="text-muted-foreground max-w-2xl text-base">
22
+ Layout helpers compose standard Tailwind spacing and semantic colors.
23
+ </p>
24
+ </section>
25
+ </main>
26
+ ),
9
27
  };
10
28
 
11
29
  export const ListRows: Story = {
12
- render: () => <main className="page-shell bg-background text-foreground"><div className="flex flex-col gap-4"><h1 className="text-4xl font-semibold tracking-tight">List row rhythm</h1><div className="divide-y divide-border border-b border-border">{["A compact row", "A readable row", "A responsive row"].map((title, index) => <div key={title} className="flex gap-4 py-6"><span className="font-mono text-sm text-muted-foreground">0{index + 1}</span><div className="flex min-w-0 flex-1 flex-col gap-1"><h2 className="text-lg font-semibold">{title}</h2><p className="text-sm text-muted-foreground">Consistent padding keeps scanning calm.</p></div></div>)}</div></div></main>,
30
+ render: () => (
31
+ <main className="page-shell bg-background text-foreground">
32
+ <div className="flex flex-col gap-4">
33
+ <h1 className="text-4xl font-semibold tracking-tight">List row rhythm</h1>
34
+ <div className="divide-border border-border divide-y border-b">
35
+ {["A compact row", "A readable row", "A responsive row"].map((title, index) => (
36
+ <div key={title} className="flex gap-4 py-6">
37
+ <span className="text-muted-foreground font-mono text-sm">0{index + 1}</span>
38
+ <div className="flex min-w-0 flex-1 flex-col gap-1">
39
+ <h2 className="text-lg font-semibold">{title}</h2>
40
+ <p className="text-muted-foreground text-sm">
41
+ Consistent padding keeps scanning calm.
42
+ </p>
43
+ </div>
44
+ </div>
45
+ ))}
46
+ </div>
47
+ </div>
48
+ </main>
49
+ ),
13
50
  };