@ponti-studios/ui 1.5.1 → 1.7.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 (77) hide show
  1. package/README.md +7 -11
  2. package/package.json +6 -31
  3. package/src/components/feedback/alert.tsx +8 -4
  4. package/src/components/feedback/index.ts +0 -4
  5. package/src/components/feedback/progress.stories.tsx +15 -0
  6. package/src/components/feedback/progress.tsx +14 -3
  7. package/src/components/feedback/update-guard.stories.tsx +4 -8
  8. package/src/components/feedback/update-guard.tsx +41 -272
  9. package/src/components/filters/filter-select.tsx +3 -5
  10. package/src/components/forms/date-picker.stories.tsx +158 -18
  11. package/src/components/forms/date-picker.tsx +286 -51
  12. package/src/components/forms/date-utils.ts +7 -2
  13. package/src/components/forms/drop-zone.tsx +11 -12
  14. package/src/components/forms/index.ts +2 -6
  15. package/src/components/forms/passkey-management.stories.tsx +8 -4
  16. package/src/components/forms/passkey-management.tsx +78 -42
  17. package/src/components/forms/radio-group.stories.tsx +3 -5
  18. package/src/components/forms/radio-group.tsx +2 -2
  19. package/src/components/forms/select.stories.tsx +16 -13
  20. package/src/components/forms/textarea.stories.tsx +1 -1
  21. package/src/components/layout/index.ts +2 -0
  22. package/src/components/layout/particle-background.stories.tsx +38 -0
  23. package/src/components/layout/particle-background.tsx +378 -0
  24. package/src/components/layout/scroll-area.stories.tsx +12 -4
  25. package/src/components/layout/scroll-area.tsx +41 -4
  26. package/src/components/navigation/tabs.stories.tsx +0 -21
  27. package/src/components/overlays/dialog.stories.tsx +38 -1
  28. package/src/components/overlays/dialog.tsx +53 -12
  29. package/src/components/overlays/index.ts +0 -11
  30. package/src/components/primitives/avatar-placeholder.svg +13 -0
  31. package/src/components/primitives/avatar.stories.tsx +2 -1
  32. package/src/components/primitives/badge.stories.tsx +13 -3
  33. package/src/components/primitives/badge.tsx +1 -1
  34. package/src/components/primitives/button.tsx +1 -1
  35. package/src/components/primitives/card.tsx +6 -2
  36. package/src/components/primitives/index.ts +0 -3
  37. package/src/index.ts +1 -3
  38. package/src/lib/index.ts +2 -3
  39. package/src/styles/animations.css +62 -0
  40. package/src/styles/index.css +27 -0
  41. package/src/styles/tokens/generated/dark.colors.generated.ts +15 -12
  42. package/src/styles/tokens/generated/dark.css +15 -12
  43. package/src/styles/tokens/generated/light.colors.generated.ts +14 -11
  44. package/src/styles/tokens/generated/light.css +14 -11
  45. package/src/styles/tokens/index.ts +0 -3
  46. package/src/styles/tokens/source/dark.tokens.json +24 -12
  47. package/src/styles/tokens/source/light.tokens.json +23 -11
  48. package/src/styles/tokens/typography.stories.tsx +157 -0
  49. package/src/components/feedback/file-upload-status.stories.tsx +0 -57
  50. package/src/components/feedback/file-upload-status.tsx +0 -160
  51. package/src/components/feedback/progress-bar.stories.tsx +0 -39
  52. package/src/components/feedback/progress-bar.tsx +0 -22
  53. package/src/components/forms/calendar.stories.tsx +0 -30
  54. package/src/components/forms/calendar.tsx +0 -70
  55. package/src/components/forms/date-field.stories.tsx +0 -164
  56. package/src/components/forms/date-field.tsx +0 -174
  57. package/src/components/overlays/alert-dialog.stories.tsx +0 -45
  58. package/src/components/overlays/alert-dialog.tsx +0 -116
  59. package/src/components/primitives/label.stories.tsx +0 -29
  60. package/src/components/primitives/label.tsx +0 -20
  61. package/src/components/primitives/status-badge.stories.tsx +0 -52
  62. package/src/components/primitives/status-badge.tsx +0 -33
  63. package/src/lib/create-memory-storage.ts +0 -24
  64. package/src/native/card.tsx +0 -36
  65. package/src/native/icon-button.tsx +0 -41
  66. package/src/native/index.ts +0 -38
  67. package/src/native/list-row.tsx +0 -67
  68. package/src/native/make-styles.ts +0 -32
  69. package/src/native/shadows.ts +0 -38
  70. package/src/native/text-field.tsx +0 -34
  71. package/src/native/uniwind.d.ts +0 -1
  72. package/src/native/use-theme-colors.ts +0 -19
  73. package/src/styles/tokens/foundations.stories.tsx +0 -109
  74. package/src/styles/tokens/generated/native.generated.ts +0 -266
  75. package/src/styles/tokens/normalize-native.ts +0 -88
  76. package/src/styles/tokens/source/native.tokens.json +0 -204
  77. package/src/styles/tokens/style-dictionary.native.mjs +0 -26
@@ -1,88 +0,0 @@
1
- import nativeGenerated from "./generated/native.generated";
2
-
3
- const toPixels = (value: string) => {
4
- if (value.endsWith("rem")) return Number.parseFloat(value) * 16;
5
- if (value.endsWith("px")) return Number.parseFloat(value);
6
- throw new Error(`Unsupported dimension: ${value}`);
7
- };
8
-
9
- const unwrap = (v: { value: number; unit?: string } | number) =>
10
- typeof v === "number" ? v : v.value;
11
-
12
- type DimensionValue = number | { value: number; unit?: string };
13
-
14
- const makeFlat = (raw: Record<string, unknown>) => ({
15
- fontFamily: raw.fontFamily as string | undefined,
16
- fontSize: unwrap(raw.fontSize as DimensionValue),
17
- fontWeight: raw.fontWeight as number,
18
- lineHeight: unwrap(raw.lineHeight as DimensionValue),
19
- letterSpacing: unwrap(raw.letterSpacing as DimensionValue),
20
- ...(raw.textTransform
21
- ? { textTransform: raw.textTransform as "uppercase" | "lowercase" | "capitalize" | "none" }
22
- : {}),
23
- });
24
-
25
- const generated = nativeGenerated as unknown as {
26
- text: Record<string, Record<string, unknown>>;
27
- space: Record<string, string>;
28
- "screen-margin": string;
29
- "component-size": Record<string, string>;
30
- "border-radius": Record<string, string>;
31
- "stream-item": Record<string, string>;
32
- "font-family": { primary: string; mono: string };
33
- };
34
-
35
- const primaryFont = generated["font-family"].primary;
36
-
37
- const typographyEntries = Object.entries(generated.text).map(([key, raw]) => {
38
- const flat = makeFlat(raw);
39
- if (!flat.fontFamily) flat.fontFamily = primaryFont;
40
- return [key, flat] as const;
41
- });
42
-
43
- export const typography = Object.fromEntries(typographyEntries) as Record<
44
- string,
45
- {
46
- fontFamily: string;
47
- fontSize: number;
48
- fontWeight: number;
49
- lineHeight: number;
50
- letterSpacing: number;
51
- textTransform?: "uppercase" | "lowercase" | "capitalize" | "none";
52
- }
53
- >;
54
-
55
- export type TypographyVariant = keyof typeof typography;
56
-
57
- export const spacing = Object.fromEntries(
58
- Object.entries(generated.space).map(([key, value]) => [key, toPixels(value)]),
59
- ) as Record<keyof typeof generated.space, number>;
60
-
61
- export type SpacingToken = keyof typeof spacing;
62
-
63
- export const screenMargin = toPixels(generated["screen-margin"]);
64
-
65
- export const componentSize = Object.fromEntries(
66
- Object.entries(generated["component-size"]).map(([key, value]) => [key, toPixels(value)]),
67
- ) as Record<keyof (typeof generated)["component-size"], number>;
68
-
69
- export type ComponentSizeToken = keyof typeof componentSize;
70
-
71
- export const borderRadius = Object.fromEntries(
72
- Object.entries(generated["border-radius"]).map(([key, value]) => [key, toPixels(value)]),
73
- ) as Record<keyof (typeof generated)["border-radius"], number>;
74
-
75
- export type BorderRadiusToken = keyof typeof borderRadius;
76
-
77
- const rawStreamItem = generated["stream-item"];
78
- export const streamItem = {
79
- borderRadius: toPixels(rawStreamItem["border-radius"]),
80
- borderWidth: toPixels(rawStreamItem["border-width"]),
81
- gap: toPixels(rawStreamItem.gap),
82
- iconSize: toPixels(rawStreamItem["icon-size"]),
83
- minHeight: toPixels(rawStreamItem["min-height"]),
84
- paddingHorizontal: toPixels(rawStreamItem["padding-horizontal"]),
85
- paddingVertical: toPixels(rawStreamItem["padding-vertical"]),
86
- };
87
-
88
- export const fontFamily = generated["font-family"];
@@ -1,204 +0,0 @@
1
- {
2
- "$extensions": {
3
- "org.ponti.description": "Semantic and component tokens for React Native consumers. Values reference the shared foundations so mobile stays in lockstep with web. Consumed via @ponti-studios/ui/native."
4
- },
5
- "space": {
6
- "$type": "dimension",
7
- "sm": { "$value": "{spacing-scale.2}" },
8
- "md": { "$value": "{spacing-scale.3}" },
9
- "lg": { "$value": "{spacing-scale.4}" },
10
- "xl": { "$value": "{spacing-scale.6}" }
11
- },
12
- "screen-margin": {
13
- "$type": "dimension",
14
- "$value": "{spacing-scale.4}"
15
- },
16
- "component-size": {
17
- "$type": "dimension",
18
- "sm": { "$value": "{spacing-scale.4}" },
19
- "md": { "$value": "{spacing-scale.6}" },
20
- "lg": { "$value": "{spacing-scale.8}" },
21
- "xl": { "$value": "{spacing-scale.11}" },
22
- "icon": { "$value": "{spacing-scale.5}" }
23
- },
24
- "border-radius": {
25
- "$type": "dimension",
26
- "sm": { "$value": "{radius.sm}" },
27
- "md": { "$value": "{radius.md}" },
28
- "lg": { "$value": "{radius.lg}" },
29
- "icon": { "$value": "{radius.md}" }
30
- },
31
- "stream-item": {
32
- "$description": "Shared flat list-row look (Inbox, Time, Tasks) — Vercel-style dense list: full-bleed bottom divider, no radius.",
33
- "$type": "dimension",
34
- "border-radius": { "$value": { "value": 0, "unit": "rem" } },
35
- "border-width": { "$value": { "value": 1, "unit": "px" } },
36
- "gap": { "$value": "{spacing-scale.3}" },
37
- "icon-size": { "$value": "{component-size.icon}" },
38
- "min-height": { "$value": "{spacing-scale.14}" },
39
- "padding-horizontal": { "$value": "{spacing-scale.4}" },
40
- "padding-vertical": { "$value": "{spacing-scale.2}" }
41
- },
42
- "font-family": {
43
- "$type": "string",
44
- "primary": { "$value": "System" },
45
- "mono": { "$value": "Menlo" }
46
- },
47
- "text": {
48
- "$description": "Apple-HIG-aligned type ramp for native editorial text.",
49
- "large-title": {
50
- "$type": "typography",
51
- "$value": {
52
- "fontSize": { "value": 34, "unit": "px" },
53
- "lineHeight": { "value": 41, "unit": "px" },
54
- "fontWeight": "{font-weight.bold}",
55
- "letterSpacing": { "value": -0.6, "unit": "px" }
56
- }
57
- },
58
- "title1": {
59
- "$type": "typography",
60
- "$value": {
61
- "fontSize": { "value": 28, "unit": "px" },
62
- "lineHeight": { "value": 34, "unit": "px" },
63
- "fontWeight": "{font-weight.bold}",
64
- "letterSpacing": { "value": -0.4, "unit": "px" }
65
- }
66
- },
67
- "title2": {
68
- "$type": "typography",
69
- "$value": {
70
- "fontSize": { "value": 22, "unit": "px" },
71
- "lineHeight": { "value": 28, "unit": "px" },
72
- "fontWeight": "{font-weight.semibold}",
73
- "letterSpacing": { "value": -0.2, "unit": "px" }
74
- }
75
- },
76
- "headline": {
77
- "$type": "typography",
78
- "$value": {
79
- "fontSize": { "value": 17, "unit": "px" },
80
- "lineHeight": { "value": 22, "unit": "px" },
81
- "fontWeight": "{font-weight.semibold}",
82
- "letterSpacing": { "value": -0.1, "unit": "px" }
83
- }
84
- },
85
- "body": {
86
- "$type": "typography",
87
- "$value": {
88
- "fontSize": { "value": 17, "unit": "px" },
89
- "lineHeight": { "value": 24, "unit": "px" },
90
- "fontWeight": "{font-weight.normal}",
91
- "letterSpacing": { "value": 0, "unit": "px" }
92
- }
93
- },
94
- "callout": {
95
- "$type": "typography",
96
- "$value": {
97
- "fontSize": { "value": 16, "unit": "px" },
98
- "lineHeight": { "value": 22, "unit": "px" },
99
- "fontWeight": "{font-weight.normal}",
100
- "letterSpacing": { "value": -0.1, "unit": "px" }
101
- }
102
- },
103
- "subhead": {
104
- "$type": "typography",
105
- "$value": {
106
- "fontSize": { "value": 15, "unit": "px" },
107
- "lineHeight": { "value": 20, "unit": "px" },
108
- "fontWeight": "{font-weight.normal}",
109
- "letterSpacing": { "value": 0, "unit": "px" }
110
- }
111
- },
112
- "footnote": {
113
- "$type": "typography",
114
- "$value": {
115
- "fontSize": { "value": 13, "unit": "px" },
116
- "lineHeight": { "value": 18, "unit": "px" },
117
- "fontWeight": "{font-weight.normal}",
118
- "letterSpacing": { "value": 0, "unit": "px" }
119
- }
120
- },
121
- "caption1": {
122
- "$type": "typography",
123
- "$value": {
124
- "fontSize": { "value": 12, "unit": "px" },
125
- "lineHeight": { "value": 16, "unit": "px" },
126
- "fontWeight": "{font-weight.normal}",
127
- "letterSpacing": { "value": 0, "unit": "px" }
128
- }
129
- },
130
- "caption2": {
131
- "$type": "typography",
132
- "$value": {
133
- "fontSize": { "value": 11, "unit": "px" },
134
- "lineHeight": { "value": 14, "unit": "px" },
135
- "fontWeight": "{font-weight.medium}",
136
- "letterSpacing": { "value": 0.2, "unit": "px" }
137
- }
138
- },
139
- "display": {
140
- "$type": "typography",
141
- "$value": {
142
- "fontSize": { "value": 40, "unit": "px" },
143
- "lineHeight": { "value": 44, "unit": "px" },
144
- "fontWeight": "{font-weight.bold}",
145
- "letterSpacing": { "value": -1.2, "unit": "px" }
146
- }
147
- },
148
- "overline": {
149
- "$type": "typography",
150
- "$value": {
151
- "fontSize": { "value": 11, "unit": "px" },
152
- "lineHeight": { "value": 16, "unit": "px" },
153
- "fontWeight": "{font-weight.medium}",
154
- "letterSpacing": { "value": 0.8, "unit": "px" },
155
- "textTransform": "uppercase"
156
- }
157
- },
158
- "mono": {
159
- "$type": "typography",
160
- "$value": {
161
- "fontFamily": "{font-family.mono}",
162
- "fontSize": { "value": 12, "unit": "px" },
163
- "lineHeight": { "value": 16, "unit": "px" },
164
- "fontWeight": "{font-weight.normal}",
165
- "letterSpacing": { "value": 0, "unit": "px" }
166
- }
167
- }
168
- },
169
- "motion": {
170
- "$description": "Portable motion semantics. Platform adapters own runtime animation objects and reduced-motion behavior.",
171
- "duration": {
172
- "$type": "duration",
173
- "instant": { "$value": "0ms" },
174
- "quick": { "$value": "{duration.150}" },
175
- "standard": { "$value": "{duration.300}" },
176
- "deliberate": { "$value": "{duration.500}" }
177
- },
178
- "easing": {
179
- "$type": "cubicBezier",
180
- "enter": { "$value": "{ease.out}" },
181
- "exit": { "$value": "{ease.in}" },
182
- "inOut": { "$value": "{ease.in-out}" }
183
- },
184
- "distance": {
185
- "$type": "dimension",
186
- "rowEnter": { "$value": "{spacing-scale.2}" },
187
- "sceneReveal": { "$value": "{spacing-scale.8}" }
188
- },
189
- "opacity": {
190
- "$type": "number",
191
- "hidden": { "$value": 0 },
192
- "visible": { "$value": 1 },
193
- "disabled": { "$value": 0.5 }
194
- },
195
- "interruption": {
196
- "$type": "string",
197
- "policy": { "$value": "cancel-and-settle" }
198
- },
199
- "reducedMotion": {
200
- "$type": "string",
201
- "policy": { "$value": "replace-transform-with-opacity" }
202
- }
203
- }
204
- }
@@ -1,26 +0,0 @@
1
- /**
2
- * Emits ONLY the native semantic/component tokens (native.tokens.json) as a
3
- * typed module. Foundations are kept in the dictionary so references resolve,
4
- * but are filtered out of the output — they already ship via
5
- * foundations.generated.ts.
6
- */
7
- export default {
8
- source: [
9
- "src/styles/tokens/source/foundations.tokens.json",
10
- "src/styles/tokens/source/native.tokens.json",
11
- ],
12
- platforms: {
13
- typescript: {
14
- transformGroup: "js",
15
- buildPath: "src/styles/tokens/generated/",
16
- files: [
17
- {
18
- destination: "native.generated.ts",
19
- format: "javascript/esm",
20
- options: { minify: true },
21
- filter: (token) => token.filePath.includes("native.tokens.json"),
22
- },
23
- ],
24
- },
25
- },
26
- };