@ornikar/bumper 3.11.0 → 3.12.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.
- package/CHANGELOG.md +11 -0
- package/dist/definitions/index.d.ts +2 -0
- package/dist/definitions/index.d.ts.map +1 -1
- package/dist/definitions/system/dataDisplays/Sticker/Sticker.d.ts +18 -0
- package/dist/definitions/system/dataDisplays/Sticker/Sticker.d.ts.map +1 -0
- package/dist/definitions/system/dataDisplays/Sticker/components/StickerLabel.d.ts +7 -0
- package/dist/definitions/system/dataDisplays/Sticker/components/StickerLabel.d.ts.map +1 -0
- package/dist/definitions/system/dataDisplays/Sticker/context.d.ts +3 -0
- package/dist/definitions/system/dataDisplays/Sticker/context.d.ts.map +1 -0
- package/dist/definitions/system/dataDisplays/Sticker/types.d.ts +24 -0
- package/dist/definitions/system/dataDisplays/Sticker/types.d.ts.map +1 -0
- package/dist/definitions/system/layout/divider/Divider.d.ts.map +1 -1
- package/dist/definitions/system/types.d.ts +10 -9
- package/dist/definitions/system/types.d.ts.map +1 -1
- package/dist/index-metro.es.android.js +146 -9
- package/dist/index-metro.es.android.js.map +1 -1
- package/dist/index-metro.es.ios.js +146 -9
- package/dist/index-metro.es.ios.js.map +1 -1
- package/dist/index-node-22.22.cjs.js +145 -6
- package/dist/index-node-22.22.cjs.js.map +1 -1
- package/dist/index-node-22.22.cjs.web.js +145 -6
- package/dist/index-node-22.22.cjs.web.js.map +1 -1
- package/dist/index-node-22.22.es.mjs +145 -7
- package/dist/index-node-22.22.es.mjs.map +1 -1
- package/dist/index-node-22.22.es.web.mjs +145 -7
- package/dist/index-node-22.22.es.web.mjs.map +1 -1
- package/dist/index.es.js +141 -9
- package/dist/index.es.js.map +1 -1
- package/dist/index.es.web.js +141 -9
- package/dist/index.es.web.js.map +1 -1
- package/dist/tsbuildinfo +1 -1
- package/docs/migration/Sticker.md +222 -0
- package/package.json +1 -1
- package/src/index.ts +2 -0
- package/src/system/dataDisplays/Sticker/Sticker.features.stories.tsx +50 -0
- package/src/system/dataDisplays/Sticker/Sticker.mdx +38 -0
- package/src/system/dataDisplays/Sticker/Sticker.stories.tsx +49 -0
- package/src/system/dataDisplays/Sticker/Sticker.tsx +52 -0
- package/src/system/dataDisplays/Sticker/__snapshots__/Sticker.features.stories.tsx.snap +747 -0
- package/src/system/dataDisplays/Sticker/__snapshots__/Sticker.stories.tsx.snap +52 -0
- package/src/system/dataDisplays/Sticker/__snapshots_web__/Sticker.features.stories.tsx.snap +294 -0
- package/src/system/dataDisplays/Sticker/__snapshots_web__/Sticker.stories.tsx.snap +35 -0
- package/src/system/dataDisplays/Sticker/components/StickerLabel.tsx +33 -0
- package/src/system/dataDisplays/Sticker/context.ts +10 -0
- package/src/system/dataDisplays/Sticker/types.ts +61 -0
- package/src/system/layout/divider/Divider.tsx +7 -2
- package/src/system/layout/divider/__snapshots_web__/Divider.features.stories.tsx.snap +7 -0
- package/src/system/layout/divider/__snapshots_web__/Divider.stories.tsx.snap +1 -0
- package/src/system/types.ts +26 -14
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# Sticker → Sticker Migration Guide
|
|
2
|
+
|
|
3
|
+
> Source: `@ornikar/kitt-universal/Sticker`
|
|
4
|
+
> Target: `@ornikar/bumper/Sticker`
|
|
5
|
+
> Generated: 2026-04-21 · Updated: 2026-04-29 (target prop reverted from `stickerColor` back to `color`)
|
|
6
|
+
|
|
7
|
+
## Import Change
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
// Before
|
|
11
|
+
import { Sticker } from '@ornikar/kitt-universal';
|
|
12
|
+
// Type imports (rare — kitt-universal only re-exports the value, not the types)
|
|
13
|
+
import type { StickerProps, StickerColor, StickerSize } from '@ornikar/kitt-universal/Sticker/Sticker';
|
|
14
|
+
|
|
15
|
+
// After
|
|
16
|
+
import { Sticker } from '@ornikar/bumper';
|
|
17
|
+
import type { StickerProps, StickerColor, StickerSize } from '@ornikar/bumper';
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Props Mapping
|
|
21
|
+
|
|
22
|
+
| Source Prop | Target Prop | Transform | Notes |
|
|
23
|
+
| ------------------- | ----------- | --------------------------- | --------------------------------------------------------------------------------------------- |
|
|
24
|
+
| `label` | `label` | Keep as-is | Same API (`ReactNode`, required) |
|
|
25
|
+
| `color` | `color` | Remap values | See [Color Value Mapping](#color-value-mapping). Default changed: `linen` → `green` |
|
|
26
|
+
| `color="disabled"` | `disabled` | Replace prop + drop value | `disabled` is now a boolean state, not a color. See [Disabled Migration](#disabled-migration) |
|
|
27
|
+
| `size` | `size` | Keep prop, values unchanged | Default changed: `medium` → `small` |
|
|
28
|
+
| `stretch` (boolean) | — | **Not migratable** | Removed from bumper. See [Stretch Removal](#stretch-removal) |
|
|
29
|
+
|
|
30
|
+
## Value Mappings
|
|
31
|
+
|
|
32
|
+
### Color Value Mapping
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
green → green (unchanged)
|
|
36
|
+
darkGreen → greenDark (camelCase order flipped)
|
|
37
|
+
blue → blue (unchanged)
|
|
38
|
+
darkBlue → blueDark (camelCase order flipped)
|
|
39
|
+
red → red (unchanged)
|
|
40
|
+
orange → orange (unchanged)
|
|
41
|
+
pink → pink (unchanged)
|
|
42
|
+
gold → gold (unchanged)
|
|
43
|
+
cream → cream (unchanged)
|
|
44
|
+
linen → linen (unchanged)
|
|
45
|
+
promo → lightning (renamed)
|
|
46
|
+
darkPromo → lightningDark (renamed + order flipped)
|
|
47
|
+
disabled → (remove color) + add `disabled` prop — see below
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Size Value Mapping
|
|
51
|
+
|
|
52
|
+
Unchanged:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
small → small
|
|
56
|
+
medium → medium
|
|
57
|
+
large → large
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Children & Composition
|
|
61
|
+
|
|
62
|
+
No change — both components accept a single `label` prop (`ReactNode`). No compound components, no children slot.
|
|
63
|
+
|
|
64
|
+
## Behavioral Differences
|
|
65
|
+
|
|
66
|
+
### Default value changes
|
|
67
|
+
|
|
68
|
+
| Prop (bumper) | kitt-universal default | bumper default | Action for migrating code |
|
|
69
|
+
| ------------- | ---------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
70
|
+
| `color` | `'linen'` | `'green'` | If source code relied on the default (`<Sticker label="x" />`), add explicit `color="linen"` to preserve appearance |
|
|
71
|
+
| `size` | `'medium'` | `'small'` | If source code relied on the default, add explicit `size="medium"` to preserve appearance |
|
|
72
|
+
|
|
73
|
+
### Typography size per `size` variant
|
|
74
|
+
|
|
75
|
+
Typography mapping is **identical** between source and target (both use the same content-caps scale):
|
|
76
|
+
|
|
77
|
+
- `size="small"` → `content-caps-xs` (12px)
|
|
78
|
+
- `size="medium"` → `content-caps-m` (16px)
|
|
79
|
+
- `size="large"` → `content-caps-l` (18px)
|
|
80
|
+
|
|
81
|
+
### Disabled visual
|
|
82
|
+
|
|
83
|
+
In kitt-universal, `color="disabled"` paints a beige background (`beige.6`) with beige text (`beige.2`). In bumper, `disabled` prop paints the semantic disabled tokens (`$bg.disabled.hi` = grey `#bababa`, `$content.disabled.onContrasted` = white @ 90%). The visual is close but not pixel-identical. Flag for design QA.
|
|
84
|
+
|
|
85
|
+
### Responsive props
|
|
86
|
+
|
|
87
|
+
bumper `Sticker` accepts Tamagui media props (`$small`, `$medium`, `$large`, `$wide`) — kitt-universal does not. No migration action needed; this is a net gain, not a break.
|
|
88
|
+
|
|
89
|
+
## Edge Cases
|
|
90
|
+
|
|
91
|
+
### Disabled migration
|
|
92
|
+
|
|
93
|
+
kitt-universal exposes `disabled` as a **color value**. bumper exposes it as a **boolean prop** — `disabled` is no longer part of the `StickerColor` union.
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
// Before — static
|
|
97
|
+
<Sticker label="Offline" color="disabled" />
|
|
98
|
+
|
|
99
|
+
// After
|
|
100
|
+
<Sticker label="Offline" disabled />
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
// Before — conditional disabled state based on a boolean
|
|
105
|
+
<Sticker label="Item" color={isInactive ? 'disabled' : 'green'} />
|
|
106
|
+
|
|
107
|
+
// After — split the condition into `disabled` + static `color`
|
|
108
|
+
<Sticker label="Item" color="green" disabled={isInactive} />
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
// Before — multi-branch conditional color including 'disabled'
|
|
113
|
+
<Sticker label="Item" color={state === 'off' ? 'disabled' : state === 'hot' ? 'red' : 'green'} />
|
|
114
|
+
|
|
115
|
+
// After — extract the disabled branch into the `disabled` prop
|
|
116
|
+
<Sticker
|
|
117
|
+
label="Item"
|
|
118
|
+
color={state === 'hot' ? 'red' : 'green'}
|
|
119
|
+
disabled={state === 'off'}
|
|
120
|
+
/>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Renamed color values in dynamic expressions
|
|
124
|
+
|
|
125
|
+
When `color` is computed dynamically, remap the values inside the expression (the prop name is unchanged):
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
// Before
|
|
129
|
+
<Sticker label={x.label} color={x.theme === 'dark' ? 'darkGreen' : 'green'} />
|
|
130
|
+
|
|
131
|
+
// After
|
|
132
|
+
<Sticker label={x.label} color={x.theme === 'dark' ? 'greenDark' : 'green'} />
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
// Before — lookup table
|
|
137
|
+
const colorMap = { success: 'green', warning: 'gold', error: 'red', paused: 'darkBlue', pro: 'promo' } as const;
|
|
138
|
+
<Sticker label={status} color={colorMap[kind]} />;
|
|
139
|
+
|
|
140
|
+
// After — rename values in the table
|
|
141
|
+
const colorMap = { success: 'green', warning: 'gold', error: 'red', paused: 'blueDark', pro: 'lightning' } as const;
|
|
142
|
+
<Sticker label={status} color={colorMap[kind]} />;
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Spread props
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
// Before
|
|
149
|
+
<Sticker {...stickerProps} />;
|
|
150
|
+
|
|
151
|
+
// After — if stickerProps may contain `stretch`, filter it out (see Stretch Removal)
|
|
152
|
+
const { stretch, ...rest } = stickerProps;
|
|
153
|
+
<Sticker {...rest} />;
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
If `stickerProps.color` may be `'disabled'` at runtime, the spread will no longer type-check. Transform dynamically:
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
// After — handle legacy 'disabled' color at call site, remap value
|
|
160
|
+
const { color, stretch, ...rest } = stickerProps;
|
|
161
|
+
<Sticker {...rest} {...(color === 'disabled' ? { disabled: true } : { color: remapColor(color) })} />;
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Stretch removal
|
|
165
|
+
|
|
166
|
+
`stretch` has no bumper equivalent. The source component used it to make the sticker `width: 100%` and center-align the label. Options:
|
|
167
|
+
|
|
168
|
+
1. **Default** — remove the prop. The sticker becomes `alignSelf: 'flex-start'` (shrink-to-content). Acceptable if the parent didn't rely on the stretch behavior.
|
|
169
|
+
2. **Preserve full-width behavior manually**:
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
// Before
|
|
173
|
+
<Sticker label="x" stretch />
|
|
174
|
+
|
|
175
|
+
// After — manual wrapper
|
|
176
|
+
<View width="100%" alignItems="center">
|
|
177
|
+
<Sticker label="x" />
|
|
178
|
+
</View>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
3. **If `stretch` was responsive** (e.g. `stretch={{ base: false, medium: true }}`), **not migratable mechanically** — flag for human review.
|
|
182
|
+
|
|
183
|
+
Any call site using `stretch` must be reviewed: the sticker's layout will change otherwise.
|
|
184
|
+
|
|
185
|
+
### Wrapper / re-export migration
|
|
186
|
+
|
|
187
|
+
If a project wraps `Sticker` in a local component, update the wrapper's imports and forward-props first (same mapping as above), then the usages resolve automatically.
|
|
188
|
+
|
|
189
|
+
If the wrapper forwards `stretch`, either drop it from the wrapper's own public API (breaking change for the wrapper) or implement the manual full-width pattern inside the wrapper.
|
|
190
|
+
|
|
191
|
+
### Styled / extended components
|
|
192
|
+
|
|
193
|
+
kitt-universal's `Sticker` uses native-base `HStack` internally and does not support being extended via `styled()`. bumper's `Sticker` is built with Tamagui but only the public `Sticker` function component is exported — **not** the underlying styled frame. If a consumer relied on `styled(Sticker)` patterns (rare), that is not migratable; use `View` + `Typography.Text` primitives to rebuild.
|
|
194
|
+
|
|
195
|
+
## Migration Rules (machine-readable)
|
|
196
|
+
|
|
197
|
+
1. Update import path: `@ornikar/kitt-universal` → `@ornikar/bumper`.
|
|
198
|
+
2. Update type imports (if any): `@ornikar/kitt-universal/Sticker/Sticker` → `@ornikar/bumper`.
|
|
199
|
+
3. Keep the component name as-is: `Sticker` → `Sticker`.
|
|
200
|
+
4. For each prop on every `<Sticker />` usage:
|
|
201
|
+
1. `label` — keep unchanged.
|
|
202
|
+
2. `color="disabled"` — **remove the `color` prop** and **add `disabled`** (boolean, `true`).
|
|
203
|
+
3. `color="darkGreen"` — remap value to `color="greenDark"`.
|
|
204
|
+
4. `color="darkBlue"` — remap value to `color="blueDark"`.
|
|
205
|
+
5. `color="promo"` — remap value to `color="lightning"`.
|
|
206
|
+
6. `color="darkPromo"` — remap value to `color="lightningDark"`.
|
|
207
|
+
7. `color` with any other static value from the union (`green`, `blue`, `red`, `orange`, `pink`, `gold`, `cream`, `linen`) — keep as-is (values unchanged).
|
|
208
|
+
8. `color` with a **dynamic expression** (ternary, lookup, variable) — keep the prop name, then recursively apply rules 4.2–4.6 to every literal value inside that expression. If the expression can evaluate to `'disabled'`, split it: extract that branch into a `disabled={…}` prop and remove `'disabled'` from the `color` expression.
|
|
209
|
+
9. `size` — keep unchanged (values are identical).
|
|
210
|
+
10. `stretch={false}` — remove the prop.
|
|
211
|
+
11. `stretch` (bare, or `={true}`, or dynamic) — **flag for manual review**. Leave the prop in place with a `// TODO: bumper Sticker has no stretch prop` comment. Do not guess.
|
|
212
|
+
5. If the call site relied on the default `color` (no `color` prop) and the visual must be preserved, add `color="linen"` explicitly.
|
|
213
|
+
6. If the call site relied on the default `size` (no `size` prop) and the visual must be preserved, add `size="medium"` explicitly.
|
|
214
|
+
7. For spread usages `<Sticker {...props} />`, do **not** rewrite the call site blindly — inspect the source type of `props` and transform the object creation site instead (or introduce a local destructure that filters `stretch` and remaps `'disabled'` to a `disabled={true}` prop, as shown in [Spread props](#spread-props)).
|
|
215
|
+
8. Do not migrate `styled(Sticker)` wrappers; flag them for manual rewrite.
|
|
216
|
+
|
|
217
|
+
## Not Migratable (requires human review)
|
|
218
|
+
|
|
219
|
+
- **`stretch` prop** — no bumper equivalent. Manual decision needed per call site: drop the prop (accept layout change), or wrap in `<View width="100%" alignItems="center">`. Responsive `stretch` values (e.g. `stretch={{ base: false, medium: true }}`) always require manual review.
|
|
220
|
+
- **`styled(Sticker)` / extended Sticker wrappers** — underlying styled component is not exported from bumper. Rebuild with primitives if needed.
|
|
221
|
+
- **Default-value regressions** — when `color` or `size` default is relied upon, the visual will change (cream pill in `medium` becomes green pill in `small`). If the migration tool cannot determine whether the default is intentional, flag the call site for design review.
|
|
222
|
+
- **Runtime-only `'disabled'` color values** — when `color` is passed as an untyped string from an external source (e.g. a CMS field), rule 4.8 cannot rewrite it statically. Add a defensive remap at the call site.
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -29,6 +29,8 @@ export type { TypographyLinkProps } from './system/content/typography/Typography
|
|
|
29
29
|
// Data Displays
|
|
30
30
|
export type { BadgeProps } from './system/dataDisplays/Badge/Badge';
|
|
31
31
|
export { Badge } from './system/dataDisplays/Badge/Badge';
|
|
32
|
+
export { Sticker } from './system/dataDisplays/Sticker/Sticker';
|
|
33
|
+
export type { StickerProps } from './system/dataDisplays/Sticker/types';
|
|
32
34
|
|
|
33
35
|
// Breakpoints
|
|
34
36
|
export { useBreakpointValue } from './system/core/breakpoints/hooks/useBreakpointValue';
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { HStack, VStack } from '../../core/primitives/Stack';
|
|
3
|
+
import { View } from '../../core/primitives/View';
|
|
4
|
+
import { Sticker } from './Sticker';
|
|
5
|
+
import { STICKER_COLORS_LIST } from './types';
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof Sticker> = {
|
|
8
|
+
title: 'Bumper/Data Displays/Sticker/Features',
|
|
9
|
+
component: Sticker,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default meta;
|
|
13
|
+
type Story = StoryObj<typeof meta>;
|
|
14
|
+
|
|
15
|
+
export const Sizes: Story = {
|
|
16
|
+
render: () => (
|
|
17
|
+
<HStack gap="$space.16" alignItems="center">
|
|
18
|
+
<Sticker label="Small" size="small" />
|
|
19
|
+
<Sticker label="Medium" size="medium" />
|
|
20
|
+
<Sticker label="Large" size="large" />
|
|
21
|
+
</HStack>
|
|
22
|
+
),
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const Colors: Story = {
|
|
26
|
+
render: () => (
|
|
27
|
+
<VStack gap="$space.8" alignItems="flex-start">
|
|
28
|
+
{STICKER_COLORS_LIST.map((color) => (
|
|
29
|
+
<Sticker key={color} label={color} color={color} />
|
|
30
|
+
))}
|
|
31
|
+
</VStack>
|
|
32
|
+
),
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const Disabled: Story = {
|
|
36
|
+
render: () => (
|
|
37
|
+
<HStack gap="$space.16" alignItems="center">
|
|
38
|
+
<Sticker label="Enabled" color="lightning" />
|
|
39
|
+
<Sticker disabled label="Disabled" color="lightning" />
|
|
40
|
+
</HStack>
|
|
41
|
+
),
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const LongLabel: Story = {
|
|
45
|
+
render: () => (
|
|
46
|
+
<View width={200}>
|
|
47
|
+
<Sticker label="A very long label that should be truncated with an ellipsis" color="linen" />
|
|
48
|
+
</View>
|
|
49
|
+
),
|
|
50
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Meta, Title, Subtitle, Primary, Controls, Canvas } from '@storybook/blocks';
|
|
2
|
+
import * as StickerStories from './Sticker.stories';
|
|
3
|
+
import * as StickerFeatures from './Sticker.features.stories';
|
|
4
|
+
|
|
5
|
+
<Meta of={StickerStories} />
|
|
6
|
+
<Title />
|
|
7
|
+
<Subtitle />
|
|
8
|
+
|
|
9
|
+
<Primary />
|
|
10
|
+
<Controls />
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
`Sticker` is a pill-shaped label used to flag status, category, or highlight content. It renders a short `label` inside a rounded container with a paired background and text color. Twelve colors are available plus three sizes (`small`, `medium`, `large`). Pass `disabled` to force the disabled color variant.
|
|
15
|
+
|
|
16
|
+
## Sizes
|
|
17
|
+
|
|
18
|
+
Three sizes cover the most common usages. Typography scales along with the container: `small` uses `content-caps-xs`, `medium` uses `content-caps-m`, `large` uses `content-caps-l`.
|
|
19
|
+
|
|
20
|
+
<Canvas of={StickerFeatures.Sizes} />
|
|
21
|
+
|
|
22
|
+
## Colors
|
|
23
|
+
|
|
24
|
+
Each color pairs a background tone with a matching text tone for legibility. Pick the color that best aligns with the surrounding context (e.g. `lightning` for promotional content, `red` for error states).
|
|
25
|
+
|
|
26
|
+
<Canvas of={StickerFeatures.Colors} />
|
|
27
|
+
|
|
28
|
+
## Disabled
|
|
29
|
+
|
|
30
|
+
`disabled` forces the internal disabled color variant, overriding any `color` prop. Use it to visually signal that the sticker's content is inactive.
|
|
31
|
+
|
|
32
|
+
<Canvas of={StickerFeatures.Disabled} />
|
|
33
|
+
|
|
34
|
+
## Truncation
|
|
35
|
+
|
|
36
|
+
Labels are truncated with an ellipsis when the sticker can't fit the full text. The sticker itself never grows beyond its parent.
|
|
37
|
+
|
|
38
|
+
<Canvas of={StickerFeatures.LongLabel} />
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { Sticker } from './Sticker';
|
|
3
|
+
import { STICKER_COLORS_LIST, STICKER_SIZES_LIST } from './types';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Sticker> = {
|
|
6
|
+
title: 'Bumper/Data Displays/Sticker',
|
|
7
|
+
component: Sticker,
|
|
8
|
+
argTypes: {
|
|
9
|
+
label: {
|
|
10
|
+
control: 'text',
|
|
11
|
+
description: 'Text content rendered inside the sticker.',
|
|
12
|
+
},
|
|
13
|
+
color: {
|
|
14
|
+
control: 'select',
|
|
15
|
+
options: STICKER_COLORS_LIST,
|
|
16
|
+
description: 'Color variant.',
|
|
17
|
+
table: {
|
|
18
|
+
defaultValue: { summary: 'green' },
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
size: {
|
|
22
|
+
control: 'select',
|
|
23
|
+
options: STICKER_SIZES_LIST,
|
|
24
|
+
description: 'Sticker size.',
|
|
25
|
+
table: {
|
|
26
|
+
defaultValue: { summary: 'small' },
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
disabled: {
|
|
30
|
+
control: 'boolean',
|
|
31
|
+
description: 'Forces the disabled color variant.',
|
|
32
|
+
table: {
|
|
33
|
+
defaultValue: { summary: 'false' },
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default meta;
|
|
40
|
+
type Story = StoryObj<typeof meta>;
|
|
41
|
+
|
|
42
|
+
export const Default: Story = {
|
|
43
|
+
args: {
|
|
44
|
+
label: 'Label',
|
|
45
|
+
color: 'green',
|
|
46
|
+
size: 'small',
|
|
47
|
+
disabled: false,
|
|
48
|
+
},
|
|
49
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { styled } from '@tamagui/core';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
import { useProps } from '../../core/hooks/useProps';
|
|
4
|
+
import type { ViewProps } from '../../core/primitives/View';
|
|
5
|
+
import { View } from '../../core/primitives/View';
|
|
6
|
+
import type { PropsToTamaguiVariants } from '../../types';
|
|
7
|
+
import { InternalStickerLabel } from './components/StickerLabel';
|
|
8
|
+
import { context } from './context';
|
|
9
|
+
import type { InternalStickerWithoutMediaProps, StickerColor, StickerProps } from './types';
|
|
10
|
+
import { STICKER_COLORS } from './types';
|
|
11
|
+
|
|
12
|
+
export const InternalStickerFrame = styled(View, {
|
|
13
|
+
name: 'Sticker',
|
|
14
|
+
context,
|
|
15
|
+
alignSelf: 'flex-start',
|
|
16
|
+
maxWidth: '100%',
|
|
17
|
+
padding: '$space.4',
|
|
18
|
+
variants: {
|
|
19
|
+
label: {},
|
|
20
|
+
size: {
|
|
21
|
+
small: { borderRadius: '$radius.s' },
|
|
22
|
+
medium: { borderRadius: '$radius.m' },
|
|
23
|
+
large: { borderRadius: '$radius.m' },
|
|
24
|
+
},
|
|
25
|
+
color: (color: StickerColor): ViewProps => {
|
|
26
|
+
const { disabled } = context.useStyledContext();
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
backgroundColor: STICKER_COLORS[disabled ? 'disabled' : color].background,
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
} as const satisfies PropsToTamaguiVariants<InternalStickerWithoutMediaProps, ViewProps>,
|
|
33
|
+
|
|
34
|
+
defaultVariants: {
|
|
35
|
+
size: 'small',
|
|
36
|
+
color: 'green',
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
export const InternalSticker = InternalStickerFrame.styleable<StickerProps>((props) => {
|
|
41
|
+
const { label, ...frameProps } = useProps(props);
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<InternalStickerFrame {...frameProps}>
|
|
45
|
+
<InternalStickerLabel>{label}</InternalStickerLabel>
|
|
46
|
+
</InternalStickerFrame>
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export function Sticker(props: StickerProps): ReactNode {
|
|
51
|
+
return <InternalSticker {...props} />;
|
|
52
|
+
}
|