@oxyhq/bloom 0.5.0 → 0.5.1
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/lib/commonjs/fonts/FontLoader.js +6 -5
- package/lib/commonjs/fonts/FontLoader.js.map +1 -1
- package/lib/commonjs/fonts/apply-font-faces.js +4 -4
- package/lib/commonjs/fonts/apply-font-faces.web.js +13 -12
- package/lib/commonjs/fonts/apply-font-faces.web.js.map +1 -1
- package/lib/commonjs/fonts/font-assets.js +2 -2
- package/lib/commonjs/fonts/font-data.web.js +22 -0
- package/lib/commonjs/fonts/font-data.web.js.map +1 -0
- package/lib/module/fonts/FontLoader.js +6 -5
- package/lib/module/fonts/FontLoader.js.map +1 -1
- package/lib/module/fonts/apply-font-faces.js +4 -4
- package/lib/module/fonts/apply-font-faces.web.js +13 -10
- package/lib/module/fonts/apply-font-faces.web.js.map +1 -1
- package/lib/module/fonts/font-assets.js +2 -2
- package/lib/module/fonts/font-data.web.js +18 -0
- package/lib/module/fonts/font-data.web.js.map +1 -0
- package/lib/module/fonts/index.web.js +4 -4
- package/lib/typescript/commonjs/fonts/FontLoader.d.ts.map +1 -1
- package/lib/typescript/commonjs/fonts/apply-font-faces.web.d.ts +8 -1
- package/lib/typescript/commonjs/fonts/apply-font-faces.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/fonts/font-data.web.d.ts +5 -0
- package/lib/typescript/commonjs/fonts/font-data.web.d.ts.map +1 -0
- package/lib/typescript/module/fonts/FontLoader.d.ts.map +1 -1
- package/lib/typescript/module/fonts/apply-font-faces.web.d.ts +8 -1
- package/lib/typescript/module/fonts/apply-font-faces.web.d.ts.map +1 -1
- package/lib/typescript/module/fonts/font-data.web.d.ts +5 -0
- package/lib/typescript/module/fonts/font-data.web.d.ts.map +1 -0
- package/package.json +36 -5
- package/src/avatar/Avatar.stories.tsx +69 -0
- package/src/bottom-sheet/BottomSheet.stories.tsx +92 -0
- package/src/button/Button.stories.tsx +94 -0
- package/src/context-menu/ContextMenu.stories.tsx +71 -0
- package/src/dialog/Dialog.stories.tsx +112 -0
- package/src/fonts/FontLoader.tsx +6 -5
- package/src/fonts/apply-font-faces.ts +4 -4
- package/src/fonts/apply-font-faces.web.ts +18 -10
- package/src/fonts/font-assets.ts +2 -2
- package/src/fonts/font-data.web.ts +15 -0
- package/src/fonts/index.web.ts +4 -4
- package/src/loading/Loading.stories.tsx +60 -0
- package/src/menu/Menu.stories.tsx +79 -0
- package/src/prompt-input/PromptInput.stories.tsx +82 -0
- package/src/select/Select.stories.tsx +84 -0
- package/src/settings-list/SettingsList.stories.tsx +106 -0
- package/src/text-field/TextField.stories.tsx +90 -0
- package/src/toast/Toast.stories.tsx +109 -0
- package/lib/commonjs/fonts/assets/BlomusModernus-Bold.woff2 +0 -0
- package/lib/commonjs/fonts/assets/BlomusModernus-Regular.woff2 +0 -0
- package/lib/commonjs/fonts/assets/GeistMono-Variable.woff2 +0 -0
- package/lib/commonjs/fonts/assets/InterVariable.woff2 +0 -0
- package/lib/module/fonts/assets/BlomusModernus-Bold.woff2 +0 -0
- package/lib/module/fonts/assets/BlomusModernus-Regular.woff2 +0 -0
- package/lib/module/fonts/assets/GeistMono-Variable.woff2 +0 -0
- package/lib/module/fonts/assets/InterVariable.woff2 +0 -0
- package/lib/typescript/commonjs/__tests__/BloomThemeProvider.fonts-web.test.d.ts +0 -5
- package/lib/typescript/commonjs/__tests__/BloomThemeProvider.fonts-web.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/BloomThemeProvider.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/BloomThemeProvider.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/BottomSheet.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/BottomSheet.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/Button.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/Button.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/Code.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/Code.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/Dialog.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/Dialog.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/FontLoader.native.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/FontLoader.native.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/Pre.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/Pre.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/SettingsList.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/SettingsList.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/apply-font-faces.test.d.ts +0 -5
- package/lib/typescript/commonjs/__tests__/apply-font-faces.test.d.ts.map +0 -1
- package/lib/typescript/commonjs/__tests__/theme.test.d.ts +0 -2
- package/lib/typescript/commonjs/__tests__/theme.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/BloomThemeProvider.fonts-web.test.d.ts +0 -5
- package/lib/typescript/module/__tests__/BloomThemeProvider.fonts-web.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/BloomThemeProvider.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/BloomThemeProvider.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/BottomSheet.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/BottomSheet.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/Button.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/Button.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/Code.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/Code.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/Dialog.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/Dialog.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/FontLoader.native.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/FontLoader.native.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/Pre.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/Pre.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/SettingsList.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/SettingsList.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/apply-font-faces.test.d.ts +0 -5
- package/lib/typescript/module/__tests__/apply-font-faces.test.d.ts.map +0 -1
- package/lib/typescript/module/__tests__/theme.test.d.ts +0 -2
- package/lib/typescript/module/__tests__/theme.test.d.ts.map +0 -1
package/src/fonts/index.web.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// Web variant of the `./fonts` barrel.
|
|
2
2
|
//
|
|
3
3
|
// The default barrel (`./index.ts`) re-exports `applyFontFaces` from
|
|
4
|
-
// `./apply-font-faces`, which on native
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
4
|
+
// `./apply-font-faces`, which on native is a no-op stub. The web fork
|
|
5
|
+
// explicitly reaches for `./apply-font-faces.web`, which performs the real
|
|
6
|
+
// `@font-face` injection using inlined base64 data URLs (see
|
|
7
|
+
// `font-data.web.ts`).
|
|
8
8
|
//
|
|
9
9
|
// Web bundlers select this file via the `"browser"` condition in
|
|
10
10
|
// `package.json`'s `exports['./fonts']`; native bundlers fall through to
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
4
|
+
|
|
5
|
+
import { Loading } from './Loading';
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof Loading> = {
|
|
8
|
+
title: 'Components/Loading',
|
|
9
|
+
component: Loading,
|
|
10
|
+
argTypes: {
|
|
11
|
+
variant: {
|
|
12
|
+
control: 'select',
|
|
13
|
+
options: ['spinner', 'top', 'skeleton', 'inline'],
|
|
14
|
+
},
|
|
15
|
+
size: {
|
|
16
|
+
control: 'select',
|
|
17
|
+
options: ['small', 'medium', 'large'],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default meta;
|
|
23
|
+
|
|
24
|
+
type Story = StoryObj<typeof Loading>;
|
|
25
|
+
|
|
26
|
+
export const Basic: Story = {
|
|
27
|
+
args: { variant: 'spinner' },
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const Spinner: Story = {
|
|
31
|
+
args: { variant: 'spinner', text: 'Loading…', showText: true },
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const Inline: Story = {
|
|
35
|
+
args: { variant: 'inline', text: 'Saving' },
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const Skeleton: Story = {
|
|
39
|
+
args: { variant: 'skeleton', lines: 4 },
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const Sizes: Story = {
|
|
43
|
+
render: () => (
|
|
44
|
+
<View style={{ flexDirection: 'row', gap: 24, alignItems: 'center' }}>
|
|
45
|
+
<Loading variant="spinner" size="small" />
|
|
46
|
+
<Loading variant="spinner" size="medium" />
|
|
47
|
+
<Loading variant="spinner" size="large" />
|
|
48
|
+
</View>
|
|
49
|
+
),
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const Composition: Story = {
|
|
53
|
+
render: () => (
|
|
54
|
+
<View style={{ gap: 24, alignItems: 'flex-start' }}>
|
|
55
|
+
<Loading variant="spinner" size="small" text="Small" />
|
|
56
|
+
<Loading variant="inline" text="Saving changes" />
|
|
57
|
+
<Loading variant="skeleton" lines={3} />
|
|
58
|
+
</View>
|
|
59
|
+
),
|
|
60
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
4
|
+
|
|
5
|
+
import { Button } from '../button';
|
|
6
|
+
import * as Menu from './index';
|
|
7
|
+
|
|
8
|
+
const meta: Meta = {
|
|
9
|
+
title: 'Components/Menu',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default meta;
|
|
13
|
+
|
|
14
|
+
type Story = StoryObj;
|
|
15
|
+
|
|
16
|
+
function BasicMenu() {
|
|
17
|
+
return (
|
|
18
|
+
<Menu.Root>
|
|
19
|
+
<Menu.Trigger label="Open menu">
|
|
20
|
+
{({ props }) => (
|
|
21
|
+
<Button onPress={props.onPress}>Open menu</Button>
|
|
22
|
+
)}
|
|
23
|
+
</Menu.Trigger>
|
|
24
|
+
<Menu.Outer>
|
|
25
|
+
<Menu.Group>
|
|
26
|
+
<Menu.Item label="Profile" onPress={() => {}}>
|
|
27
|
+
<Menu.ItemText>Profile</Menu.ItemText>
|
|
28
|
+
</Menu.Item>
|
|
29
|
+
<Menu.Item label="Settings" onPress={() => {}}>
|
|
30
|
+
<Menu.ItemText>Settings</Menu.ItemText>
|
|
31
|
+
</Menu.Item>
|
|
32
|
+
<Menu.Item label="Sign out" onPress={() => {}}>
|
|
33
|
+
<Menu.ItemText>Sign out</Menu.ItemText>
|
|
34
|
+
</Menu.Item>
|
|
35
|
+
</Menu.Group>
|
|
36
|
+
</Menu.Outer>
|
|
37
|
+
</Menu.Root>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function MenuWithDisabledItem() {
|
|
42
|
+
return (
|
|
43
|
+
<Menu.Root>
|
|
44
|
+
<Menu.Trigger label="Open menu with disabled item">
|
|
45
|
+
{({ props }) => <Button onPress={props.onPress}>Open</Button>}
|
|
46
|
+
</Menu.Trigger>
|
|
47
|
+
<Menu.Outer>
|
|
48
|
+
<Menu.Group>
|
|
49
|
+
<Menu.Item label="Edit" onPress={() => {}}>
|
|
50
|
+
<Menu.ItemText>Edit</Menu.ItemText>
|
|
51
|
+
</Menu.Item>
|
|
52
|
+
<Menu.Item label="Duplicate" onPress={() => {}} disabled>
|
|
53
|
+
<Menu.ItemText>Duplicate (disabled)</Menu.ItemText>
|
|
54
|
+
</Menu.Item>
|
|
55
|
+
<Menu.Item label="Delete" onPress={() => {}}>
|
|
56
|
+
<Menu.ItemText>Delete</Menu.ItemText>
|
|
57
|
+
</Menu.Item>
|
|
58
|
+
</Menu.Group>
|
|
59
|
+
</Menu.Outer>
|
|
60
|
+
</Menu.Root>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export const Basic: Story = {
|
|
65
|
+
render: () => <BasicMenu />,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const WithDisabled: Story = {
|
|
69
|
+
render: () => <MenuWithDisabledItem />,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const Composition: Story = {
|
|
73
|
+
render: () => (
|
|
74
|
+
<View style={{ gap: 12, alignItems: 'flex-start' }}>
|
|
75
|
+
<BasicMenu />
|
|
76
|
+
<MenuWithDisabledItem />
|
|
77
|
+
</View>
|
|
78
|
+
),
|
|
79
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
4
|
+
|
|
5
|
+
import { PromptInput } from './PromptInput';
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof PromptInput> = {
|
|
8
|
+
title: 'Components/PromptInput',
|
|
9
|
+
component: PromptInput,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default meta;
|
|
13
|
+
|
|
14
|
+
type Story = StoryObj<typeof PromptInput>;
|
|
15
|
+
|
|
16
|
+
function BasicPrompt() {
|
|
17
|
+
const [value, setValue] = useState('');
|
|
18
|
+
return (
|
|
19
|
+
<View style={{ width: 480 }}>
|
|
20
|
+
<PromptInput
|
|
21
|
+
value={value}
|
|
22
|
+
onValueChange={setValue}
|
|
23
|
+
placeholder="Ask anything"
|
|
24
|
+
onSubmit={() => {
|
|
25
|
+
// submitted
|
|
26
|
+
setValue('');
|
|
27
|
+
}}
|
|
28
|
+
/>
|
|
29
|
+
</View>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function LoadingPrompt() {
|
|
34
|
+
const [value, setValue] = useState('Generating response...');
|
|
35
|
+
return (
|
|
36
|
+
<View style={{ width: 480 }}>
|
|
37
|
+
<PromptInput
|
|
38
|
+
value={value}
|
|
39
|
+
onValueChange={setValue}
|
|
40
|
+
placeholder="Ask anything"
|
|
41
|
+
isLoading
|
|
42
|
+
onSubmit={() => {}}
|
|
43
|
+
onStop={() => {}}
|
|
44
|
+
/>
|
|
45
|
+
</View>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function DisabledPrompt() {
|
|
50
|
+
return (
|
|
51
|
+
<View style={{ width: 480 }}>
|
|
52
|
+
<PromptInput
|
|
53
|
+
value=""
|
|
54
|
+
placeholder="Disabled"
|
|
55
|
+
disabled
|
|
56
|
+
onSubmit={() => {}}
|
|
57
|
+
/>
|
|
58
|
+
</View>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const Basic: Story = {
|
|
63
|
+
render: () => <BasicPrompt />,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const Loading: Story = {
|
|
67
|
+
render: () => <LoadingPrompt />,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const Disabled: Story = {
|
|
71
|
+
render: () => <DisabledPrompt />,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const Composition: Story = {
|
|
75
|
+
render: () => (
|
|
76
|
+
<View style={{ gap: 16 }}>
|
|
77
|
+
<BasicPrompt />
|
|
78
|
+
<LoadingPrompt />
|
|
79
|
+
<DisabledPrompt />
|
|
80
|
+
</View>
|
|
81
|
+
),
|
|
82
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
4
|
+
|
|
5
|
+
import * as Select from './index';
|
|
6
|
+
|
|
7
|
+
const meta: Meta = {
|
|
8
|
+
title: 'Components/Select',
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default meta;
|
|
12
|
+
|
|
13
|
+
type Story = StoryObj;
|
|
14
|
+
|
|
15
|
+
type Option = { value: string; label: string };
|
|
16
|
+
|
|
17
|
+
const FRUITS: Option[] = [
|
|
18
|
+
{ value: 'apple', label: 'Apple' },
|
|
19
|
+
{ value: 'banana', label: 'Banana' },
|
|
20
|
+
{ value: 'cherry', label: 'Cherry' },
|
|
21
|
+
{ value: 'durian', label: 'Durian' },
|
|
22
|
+
{ value: 'elderberry', label: 'Elderberry' },
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
function BasicSelect() {
|
|
26
|
+
const [value, setValue] = useState<string>('apple');
|
|
27
|
+
return (
|
|
28
|
+
<Select.Root value={value} onValueChange={setValue}>
|
|
29
|
+
<Select.Trigger label="Pick a fruit">
|
|
30
|
+
<Select.ValueText placeholder="Pick a fruit" />
|
|
31
|
+
<Select.Icon />
|
|
32
|
+
</Select.Trigger>
|
|
33
|
+
<Select.Content
|
|
34
|
+
label="Pick a fruit"
|
|
35
|
+
items={FRUITS}
|
|
36
|
+
renderItem={(item) => (
|
|
37
|
+
<Select.Item value={item.value} label={item.label}>
|
|
38
|
+
<Select.ItemIndicator />
|
|
39
|
+
<Select.ItemText>{item.label}</Select.ItemText>
|
|
40
|
+
</Select.Item>
|
|
41
|
+
)}
|
|
42
|
+
/>
|
|
43
|
+
</Select.Root>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function UncontrolledSelect() {
|
|
48
|
+
const [value, setValue] = useState<string | undefined>(undefined);
|
|
49
|
+
return (
|
|
50
|
+
<Select.Root value={value} onValueChange={setValue}>
|
|
51
|
+
<Select.Trigger label="Pick a fruit">
|
|
52
|
+
<Select.ValueText placeholder="No fruit selected" />
|
|
53
|
+
<Select.Icon />
|
|
54
|
+
</Select.Trigger>
|
|
55
|
+
<Select.Content
|
|
56
|
+
label="Pick a fruit"
|
|
57
|
+
items={FRUITS}
|
|
58
|
+
renderItem={(item) => (
|
|
59
|
+
<Select.Item value={item.value} label={item.label}>
|
|
60
|
+
<Select.ItemIndicator />
|
|
61
|
+
<Select.ItemText>{item.label}</Select.ItemText>
|
|
62
|
+
</Select.Item>
|
|
63
|
+
)}
|
|
64
|
+
/>
|
|
65
|
+
</Select.Root>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const Basic: Story = {
|
|
70
|
+
render: () => <BasicSelect />,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const WithPlaceholder: Story = {
|
|
74
|
+
render: () => <UncontrolledSelect />,
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const Composition: Story = {
|
|
78
|
+
render: () => (
|
|
79
|
+
<View style={{ gap: 16 }}>
|
|
80
|
+
<BasicSelect />
|
|
81
|
+
<UncontrolledSelect />
|
|
82
|
+
</View>
|
|
83
|
+
),
|
|
84
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
4
|
+
|
|
5
|
+
import { Switch } from '../switch';
|
|
6
|
+
import {
|
|
7
|
+
SettingsListGroup,
|
|
8
|
+
SettingsListItem,
|
|
9
|
+
SettingsListDivider,
|
|
10
|
+
} from './SettingsList';
|
|
11
|
+
|
|
12
|
+
const meta: Meta = {
|
|
13
|
+
title: 'Components/SettingsList',
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default meta;
|
|
17
|
+
|
|
18
|
+
type Story = StoryObj;
|
|
19
|
+
|
|
20
|
+
function BasicList() {
|
|
21
|
+
return (
|
|
22
|
+
<View style={{ width: 360 }}>
|
|
23
|
+
<SettingsListGroup title="Account">
|
|
24
|
+
<SettingsListItem
|
|
25
|
+
title="Profile"
|
|
26
|
+
description="Manage your account profile"
|
|
27
|
+
onPress={() => {}}
|
|
28
|
+
/>
|
|
29
|
+
<SettingsListItem
|
|
30
|
+
title="Email"
|
|
31
|
+
value="nate@oxy.so"
|
|
32
|
+
onPress={() => {}}
|
|
33
|
+
/>
|
|
34
|
+
<SettingsListItem
|
|
35
|
+
title="Sign out"
|
|
36
|
+
destructive
|
|
37
|
+
onPress={() => {}}
|
|
38
|
+
/>
|
|
39
|
+
</SettingsListGroup>
|
|
40
|
+
</View>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function WithToggles() {
|
|
45
|
+
const [notifs, setNotifs] = useState(true);
|
|
46
|
+
const [dark, setDark] = useState(false);
|
|
47
|
+
return (
|
|
48
|
+
<View style={{ width: 360 }}>
|
|
49
|
+
<SettingsListGroup title="Preferences" footer="Changes apply immediately.">
|
|
50
|
+
<SettingsListItem
|
|
51
|
+
title="Push notifications"
|
|
52
|
+
rightElement={
|
|
53
|
+
<Switch value={notifs} onValueChange={setNotifs} />
|
|
54
|
+
}
|
|
55
|
+
showChevron={false}
|
|
56
|
+
/>
|
|
57
|
+
<SettingsListItem
|
|
58
|
+
title="Dark mode"
|
|
59
|
+
rightElement={<Switch value={dark} onValueChange={setDark} />}
|
|
60
|
+
showChevron={false}
|
|
61
|
+
/>
|
|
62
|
+
</SettingsListGroup>
|
|
63
|
+
</View>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function DescriptionList() {
|
|
68
|
+
return (
|
|
69
|
+
<View style={{ width: 360 }}>
|
|
70
|
+
<SettingsListGroup title="Security">
|
|
71
|
+
<SettingsListItem
|
|
72
|
+
title="Two-factor authentication"
|
|
73
|
+
description="Add an extra layer of security to your account."
|
|
74
|
+
onPress={() => {}}
|
|
75
|
+
/>
|
|
76
|
+
<SettingsListItem
|
|
77
|
+
title="Active sessions"
|
|
78
|
+
description="View where your account is signed in."
|
|
79
|
+
onPress={() => {}}
|
|
80
|
+
/>
|
|
81
|
+
</SettingsListGroup>
|
|
82
|
+
</View>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export const Basic: Story = {
|
|
87
|
+
render: () => <BasicList />,
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const WithRightElements: Story = {
|
|
91
|
+
render: () => <WithToggles />,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export const WithDescriptions: Story = {
|
|
95
|
+
render: () => <DescriptionList />,
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const Composition: Story = {
|
|
99
|
+
render: () => (
|
|
100
|
+
<View style={{ gap: 24, width: 360 }}>
|
|
101
|
+
<DescriptionList />
|
|
102
|
+
<SettingsListDivider />
|
|
103
|
+
<WithToggles />
|
|
104
|
+
</View>
|
|
105
|
+
),
|
|
106
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
4
|
+
|
|
5
|
+
import * as TextField from './index';
|
|
6
|
+
|
|
7
|
+
const meta: Meta = {
|
|
8
|
+
title: 'Components/TextField',
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default meta;
|
|
12
|
+
|
|
13
|
+
type Story = StoryObj;
|
|
14
|
+
|
|
15
|
+
function ControlledField({
|
|
16
|
+
label,
|
|
17
|
+
placeholder,
|
|
18
|
+
initial = '',
|
|
19
|
+
isInvalid,
|
|
20
|
+
editable = true,
|
|
21
|
+
}: {
|
|
22
|
+
label: string;
|
|
23
|
+
placeholder?: string;
|
|
24
|
+
initial?: string;
|
|
25
|
+
isInvalid?: boolean;
|
|
26
|
+
editable?: boolean;
|
|
27
|
+
}) {
|
|
28
|
+
const [value, setValue] = useState(initial);
|
|
29
|
+
return (
|
|
30
|
+
<View style={{ width: 320 }}>
|
|
31
|
+
<TextField.LabelText>{label}</TextField.LabelText>
|
|
32
|
+
<TextField.Root isInvalid={isInvalid}>
|
|
33
|
+
<TextField.Input
|
|
34
|
+
label={label}
|
|
35
|
+
placeholder={placeholder}
|
|
36
|
+
value={value}
|
|
37
|
+
onChangeText={setValue}
|
|
38
|
+
editable={editable}
|
|
39
|
+
isInvalid={isInvalid}
|
|
40
|
+
/>
|
|
41
|
+
</TextField.Root>
|
|
42
|
+
</View>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const Basic: Story = {
|
|
47
|
+
render: () => (
|
|
48
|
+
<ControlledField label="Username" placeholder="oxylander" />
|
|
49
|
+
),
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const WithValue: Story = {
|
|
53
|
+
render: () => (
|
|
54
|
+
<ControlledField label="Email" initial="nate@oxy.so" />
|
|
55
|
+
),
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const Error: Story = {
|
|
59
|
+
render: () => (
|
|
60
|
+
<ControlledField
|
|
61
|
+
label="Email"
|
|
62
|
+
initial="not-an-email"
|
|
63
|
+
isInvalid
|
|
64
|
+
/>
|
|
65
|
+
),
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const Disabled: Story = {
|
|
69
|
+
render: () => (
|
|
70
|
+
<ControlledField
|
|
71
|
+
label="Username"
|
|
72
|
+
initial="oxylander"
|
|
73
|
+
editable={false}
|
|
74
|
+
/>
|
|
75
|
+
),
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const Composition: Story = {
|
|
79
|
+
render: () => (
|
|
80
|
+
<View style={{ gap: 16 }}>
|
|
81
|
+
<ControlledField label="First name" placeholder="Ada" />
|
|
82
|
+
<ControlledField label="Last name" placeholder="Lovelace" />
|
|
83
|
+
<ControlledField
|
|
84
|
+
label="Email"
|
|
85
|
+
initial="invalid-email"
|
|
86
|
+
isInvalid
|
|
87
|
+
/>
|
|
88
|
+
</View>
|
|
89
|
+
),
|
|
90
|
+
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
4
|
+
|
|
5
|
+
import { Button } from '../button';
|
|
6
|
+
import { toast, ToastOutlet } from './index';
|
|
7
|
+
|
|
8
|
+
const meta: Meta = {
|
|
9
|
+
title: 'Components/Toast',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default meta;
|
|
13
|
+
|
|
14
|
+
type Story = StoryObj;
|
|
15
|
+
|
|
16
|
+
function ToastDemo({
|
|
17
|
+
variant,
|
|
18
|
+
message,
|
|
19
|
+
}: {
|
|
20
|
+
variant: 'default' | 'success' | 'error' | 'warning' | 'info';
|
|
21
|
+
message: string;
|
|
22
|
+
}) {
|
|
23
|
+
const fire = () => {
|
|
24
|
+
switch (variant) {
|
|
25
|
+
case 'success':
|
|
26
|
+
toast.success(message);
|
|
27
|
+
return;
|
|
28
|
+
case 'error':
|
|
29
|
+
toast.error(message);
|
|
30
|
+
return;
|
|
31
|
+
case 'warning':
|
|
32
|
+
toast.warning(message);
|
|
33
|
+
return;
|
|
34
|
+
case 'info':
|
|
35
|
+
toast.info(message);
|
|
36
|
+
return;
|
|
37
|
+
case 'default':
|
|
38
|
+
default:
|
|
39
|
+
toast(message);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<Button onPress={fire}>{`Show ${variant}`}</Button>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function Outlet() {
|
|
49
|
+
return <ToastOutlet />;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const Basic: Story = {
|
|
53
|
+
render: () => (
|
|
54
|
+
<View style={{ gap: 12, alignItems: 'flex-start' }}>
|
|
55
|
+
<ToastDemo variant="default" message="Saved" />
|
|
56
|
+
<Outlet />
|
|
57
|
+
</View>
|
|
58
|
+
),
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const Success: Story = {
|
|
62
|
+
render: () => (
|
|
63
|
+
<View style={{ gap: 12, alignItems: 'flex-start' }}>
|
|
64
|
+
<ToastDemo variant="success" message="Profile updated" />
|
|
65
|
+
<Outlet />
|
|
66
|
+
</View>
|
|
67
|
+
),
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const ErrorToast: Story = {
|
|
71
|
+
name: 'Error',
|
|
72
|
+
render: () => (
|
|
73
|
+
<View style={{ gap: 12, alignItems: 'flex-start' }}>
|
|
74
|
+
<ToastDemo variant="error" message="Network error" />
|
|
75
|
+
<Outlet />
|
|
76
|
+
</View>
|
|
77
|
+
),
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const Warning: Story = {
|
|
81
|
+
render: () => (
|
|
82
|
+
<View style={{ gap: 12, alignItems: 'flex-start' }}>
|
|
83
|
+
<ToastDemo variant="warning" message="Storage almost full" />
|
|
84
|
+
<Outlet />
|
|
85
|
+
</View>
|
|
86
|
+
),
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export const Info: Story = {
|
|
90
|
+
render: () => (
|
|
91
|
+
<View style={{ gap: 12, alignItems: 'flex-start' }}>
|
|
92
|
+
<ToastDemo variant="info" message="New version available" />
|
|
93
|
+
<Outlet />
|
|
94
|
+
</View>
|
|
95
|
+
),
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const Composition: Story = {
|
|
99
|
+
render: () => (
|
|
100
|
+
<View style={{ gap: 12, alignItems: 'flex-start' }}>
|
|
101
|
+
<ToastDemo variant="default" message="Default" />
|
|
102
|
+
<ToastDemo variant="success" message="Success" />
|
|
103
|
+
<ToastDemo variant="error" message="Error" />
|
|
104
|
+
<ToastDemo variant="warning" message="Warning" />
|
|
105
|
+
<ToastDemo variant="info" message="Info" />
|
|
106
|
+
<Outlet />
|
|
107
|
+
</View>
|
|
108
|
+
),
|
|
109
|
+
};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BloomThemeProvider.fonts-web.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/BloomThemeProvider.fonts-web.test.tsx"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BloomThemeProvider.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/BloomThemeProvider.test.tsx"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BottomSheet.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/BottomSheet.test.tsx"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Button.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/Button.test.tsx"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Code.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/Code.test.tsx"],"names":[],"mappings":""}
|