@dxos/ui-theme 0.0.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/LICENSE +8 -0
- package/README.md +25 -0
- package/package.json +80 -0
- package/src/Tokens.stories.tsx +88 -0
- package/src/config/index.ts +6 -0
- package/src/config/tailwind.ts +250 -0
- package/src/config/tokens/alias-colors.ts +39 -0
- package/src/config/tokens/index.ts +92 -0
- package/src/config/tokens/lengths.ts +97 -0
- package/src/config/tokens/physical-colors.ts +125 -0
- package/src/config/tokens/semantic-colors.ts +27 -0
- package/src/config/tokens/sememes-calls.ts +17 -0
- package/src/config/tokens/sememes-codemirror.ts +50 -0
- package/src/config/tokens/sememes-hue.ts +54 -0
- package/src/config/tokens/sememes-sheet.ts +62 -0
- package/src/config/tokens/sememes-system.ts +302 -0
- package/src/config/tokens/sizes.ts +7 -0
- package/src/config/tokens/types.ts +9 -0
- package/src/docs/theme.drawio.svg +635 -0
- package/src/index.ts +19 -0
- package/src/plugins/esbuild-plugin.ts +65 -0
- package/src/plugins/plugin.ts +130 -0
- package/src/plugins/resolveContent.ts +51 -0
- package/src/styles/components/README.md +6 -0
- package/src/styles/components/anchored-overflow.ts +20 -0
- package/src/styles/components/avatar.ts +96 -0
- package/src/styles/components/breadcrumb.ts +29 -0
- package/src/styles/components/button.ts +48 -0
- package/src/styles/components/dialog.ts +36 -0
- package/src/styles/components/icon-button.ts +20 -0
- package/src/styles/components/icon.ts +19 -0
- package/src/styles/components/index.ts +27 -0
- package/src/styles/components/input.ts +177 -0
- package/src/styles/components/link.ts +26 -0
- package/src/styles/components/list.ts +46 -0
- package/src/styles/components/main.ts +36 -0
- package/src/styles/components/menu.ts +60 -0
- package/src/styles/components/message.ts +36 -0
- package/src/styles/components/popover.ts +40 -0
- package/src/styles/components/scroll-area.ts +43 -0
- package/src/styles/components/select.ts +60 -0
- package/src/styles/components/separator.ts +24 -0
- package/src/styles/components/status.ts +32 -0
- package/src/styles/components/tag.ts +23 -0
- package/src/styles/components/toast.ts +55 -0
- package/src/styles/components/toolbar.ts +29 -0
- package/src/styles/components/tooltip.ts +29 -0
- package/src/styles/components/treegrid.ts +37 -0
- package/src/styles/fragments/density.ts +17 -0
- package/src/styles/fragments/dimension.ts +8 -0
- package/src/styles/fragments/disabled.ts +6 -0
- package/src/styles/fragments/elevation.ts +29 -0
- package/src/styles/fragments/focus.ts +16 -0
- package/src/styles/fragments/group.ts +12 -0
- package/src/styles/fragments/hover.ts +25 -0
- package/src/styles/fragments/index.ts +20 -0
- package/src/styles/fragments/layout.ts +7 -0
- package/src/styles/fragments/motion.ts +6 -0
- package/src/styles/fragments/ornament.ts +10 -0
- package/src/styles/fragments/selected.ts +45 -0
- package/src/styles/fragments/shimmer.ts +9 -0
- package/src/styles/fragments/size.ts +117 -0
- package/src/styles/fragments/surface.ts +29 -0
- package/src/styles/fragments/text.ts +12 -0
- package/src/styles/fragments/valence.ts +46 -0
- package/src/styles/index.ts +7 -0
- package/src/styles/layers/README.md +15 -0
- package/src/styles/layers/anchored-overflow.css +9 -0
- package/src/styles/layers/animation.css +17 -0
- package/src/styles/layers/attention.css +8 -0
- package/src/styles/layers/base.css +25 -0
- package/src/styles/layers/button.css +76 -0
- package/src/styles/layers/can-scroll.css +26 -0
- package/src/styles/layers/checkbox.css +50 -0
- package/src/styles/layers/dialog.css +42 -0
- package/src/styles/layers/drag-preview.css +18 -0
- package/src/styles/layers/focus-ring.css +224 -0
- package/src/styles/layers/hues.css +110 -0
- package/src/styles/layers/index.css +26 -0
- package/src/styles/layers/main.css +160 -0
- package/src/styles/layers/native.css +20 -0
- package/src/styles/layers/positioning.css +23 -0
- package/src/styles/layers/size.css +397 -0
- package/src/styles/layers/surfaces.css +31 -0
- package/src/styles/layers/tag.css +132 -0
- package/src/styles/layers/tldraw.css +91 -0
- package/src/styles/layers/tokens.css +45 -0
- package/src/styles/layers/typography.css +157 -0
- package/src/styles/theme.ts +69 -0
- package/src/tailwind.ts +5 -0
- package/src/theme.css +9 -0
- package/src/types.ts +7 -0
- package/src/typings.d.ts +8 -0
- package/src/util/hash-styles.ts +168 -0
- package/src/util/index.ts +6 -0
- package/src/util/mx.ts +51 -0
- package/src/util/withLogical.ts +114 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
type ComponentFragment,
|
|
7
|
+
type ComponentFunction,
|
|
8
|
+
type Density,
|
|
9
|
+
type Elevation,
|
|
10
|
+
type MessageValence,
|
|
11
|
+
type Size,
|
|
12
|
+
} from '@dxos/ui-types';
|
|
13
|
+
|
|
14
|
+
import { mx } from '../../util';
|
|
15
|
+
import {
|
|
16
|
+
coarseBlockSize,
|
|
17
|
+
coarseDimensions,
|
|
18
|
+
computeSize,
|
|
19
|
+
descriptionText,
|
|
20
|
+
fineBlockSize,
|
|
21
|
+
fineDimensions,
|
|
22
|
+
focusRing,
|
|
23
|
+
getSize,
|
|
24
|
+
getSizeHeight,
|
|
25
|
+
getSizeWidth,
|
|
26
|
+
placeholderText,
|
|
27
|
+
sizeValue,
|
|
28
|
+
staticDisabled,
|
|
29
|
+
staticFocusRing,
|
|
30
|
+
subduedFocus,
|
|
31
|
+
valenceColorText,
|
|
32
|
+
} from '../fragments';
|
|
33
|
+
|
|
34
|
+
export type InputStyleProps = Partial<{
|
|
35
|
+
variant: 'default' | 'subdued' | 'static';
|
|
36
|
+
density: Density;
|
|
37
|
+
disabled: boolean;
|
|
38
|
+
elevation: Elevation;
|
|
39
|
+
focused: boolean;
|
|
40
|
+
validationValence: MessageValence;
|
|
41
|
+
size: Size;
|
|
42
|
+
checked: boolean;
|
|
43
|
+
}>;
|
|
44
|
+
|
|
45
|
+
export type InputMetaStyleProps = Partial<{
|
|
46
|
+
srOnly: boolean;
|
|
47
|
+
validationValence: MessageValence;
|
|
48
|
+
}>;
|
|
49
|
+
|
|
50
|
+
export const neutralInputValence = '';
|
|
51
|
+
export const successInputValence = 'shadow-emerald-500/50 dark:shadow-emerald-600/50';
|
|
52
|
+
export const infoInputValence = 'shadow-cyan-500/50 dark:shadow-cyan-600/50';
|
|
53
|
+
export const warningInputValence = 'shadow-amber-500/50 dark:shadow-amber-600/50';
|
|
54
|
+
export const errorInputValence = 'shadow-rose-500/50 dark:shadow-rose-600/50';
|
|
55
|
+
|
|
56
|
+
const textInputSurfaceFocus =
|
|
57
|
+
'transition-colors bg-textInputSurface focus:bg-focusSurface border border-separator focus:border-separator';
|
|
58
|
+
|
|
59
|
+
const textInputSurfaceHover = 'hover:bg-textInputSurface focus:hover:bg-focusSurface';
|
|
60
|
+
|
|
61
|
+
const booleanInputSurface =
|
|
62
|
+
'shadow-inner transition-colors bg-unAccent aria-checked:bg-accentSurface aria-[checked=mixed]:bg-accentSurface';
|
|
63
|
+
|
|
64
|
+
const booleanInputSurfaceHover =
|
|
65
|
+
'hover:bg-unAccentHover hover:aria-checked:bg-accentSurfaceHover hover:aria-[checked=mixed]:bg-accentSurfaceHover';
|
|
66
|
+
|
|
67
|
+
export const inputTextLabel =
|
|
68
|
+
'text-description text-xs font-medium mbs-inputSpacingBlock mbe-labelSpacingBlock first:mbs-0';
|
|
69
|
+
|
|
70
|
+
export const inputValence = (valence?: MessageValence) => {
|
|
71
|
+
switch (valence) {
|
|
72
|
+
case 'success':
|
|
73
|
+
return successInputValence;
|
|
74
|
+
case 'info':
|
|
75
|
+
return infoInputValence;
|
|
76
|
+
case 'warning':
|
|
77
|
+
return warningInputValence;
|
|
78
|
+
case 'error':
|
|
79
|
+
return errorInputValence;
|
|
80
|
+
default:
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// TODO(burdon): Factor out color defs?
|
|
86
|
+
|
|
87
|
+
const sharedSubduedInputStyles: ComponentFragment<InputStyleProps> = (props) => [
|
|
88
|
+
'plb-0 is-full bg-transparent text-current [[data-drag-autoscroll="active"]_&]:pointer-events-none',
|
|
89
|
+
props.density === 'fine' ? fineBlockSize : coarseBlockSize,
|
|
90
|
+
placeholderText,
|
|
91
|
+
subduedFocus,
|
|
92
|
+
props.disabled && staticDisabled,
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
const sharedDefaultInputStyles: ComponentFragment<InputStyleProps> = (props) => [
|
|
96
|
+
'plb-0 is-full text-baseText rounded-sm text-[color:var(--surface-text)] [[data-drag-autoscroll="active"]_&]:pointer-events-none',
|
|
97
|
+
textInputSurfaceFocus,
|
|
98
|
+
placeholderText,
|
|
99
|
+
props.density === 'fine' ? fineDimensions : coarseDimensions,
|
|
100
|
+
props.disabled ? staticDisabled : textInputSurfaceHover,
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
const sharedStaticInputStyles: ComponentFragment<InputStyleProps> = (props) => [
|
|
104
|
+
'plb-0 is-full text-baseText rounded-sm text-[color:var(--surface-text)] [[data-drag-autoscroll="active"]_&]:pointer-events-none',
|
|
105
|
+
textInputSurfaceFocus,
|
|
106
|
+
textInputSurfaceHover,
|
|
107
|
+
props.focused && 'bg-attention',
|
|
108
|
+
placeholderText,
|
|
109
|
+
inputValence(props.validationValence),
|
|
110
|
+
props.disabled && staticDisabled,
|
|
111
|
+
props.focused && staticFocusRing,
|
|
112
|
+
];
|
|
113
|
+
|
|
114
|
+
export const inputInput: ComponentFunction<InputStyleProps> = (props, ...etc) =>
|
|
115
|
+
props.variant === 'subdued'
|
|
116
|
+
? mx(...sharedSubduedInputStyles(props), ...etc)
|
|
117
|
+
: props.variant === 'static'
|
|
118
|
+
? mx(...sharedStaticInputStyles(props), ...etc)
|
|
119
|
+
: mx(
|
|
120
|
+
...sharedDefaultInputStyles(props),
|
|
121
|
+
!props.disabled && focusRing,
|
|
122
|
+
inputValence(props.validationValence) || neutralInputValence,
|
|
123
|
+
...etc,
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
export const inputCheckbox: ComponentFunction<InputStyleProps> = ({ size = 5 }, ...etc) =>
|
|
127
|
+
mx('dx-checkbox dx-focus-ring', getSize(size), ...etc);
|
|
128
|
+
|
|
129
|
+
export const inputCheckboxIndicator: ComponentFunction<InputStyleProps> = ({ size = 5, checked }, ...etc) =>
|
|
130
|
+
mx(getSize(computeSize(sizeValue(size) * 0.65, 4)), !checked && 'invisible', ...etc);
|
|
131
|
+
|
|
132
|
+
export const inputSwitch: ComponentFunction<InputStyleProps> = ({ size = 5, disabled }, ...etc) =>
|
|
133
|
+
mx(
|
|
134
|
+
getSizeHeight(size),
|
|
135
|
+
getSizeWidth(computeSize(sizeValue(size) * 1.75, 9)),
|
|
136
|
+
booleanInputSurface,
|
|
137
|
+
!disabled && booleanInputSurfaceHover,
|
|
138
|
+
// TODO(burdon): Added m-1 margin to make 40px width to align with 40px icon button.
|
|
139
|
+
'cursor-pointer shrink-0 rounded-full pli-1 mx-1 relative',
|
|
140
|
+
focusRing,
|
|
141
|
+
...etc,
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
export const inputSwitchThumb: ComponentFunction<InputStyleProps> = ({ size = 5 }, ...etc) =>
|
|
145
|
+
mx(
|
|
146
|
+
getSize(size === 'px' ? 'px' : ((size - 2) as Size)),
|
|
147
|
+
'block bg-white rounded-full transition-transform duration-100 will-change-transform data-[state=checked]:translate-x-[100%]',
|
|
148
|
+
...etc,
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
export const inputWithSegmentsInput: ComponentFunction<InputStyleProps> = (props, ...etc) =>
|
|
152
|
+
mx('font-mono selection:bg-transparent mli-auto', props.disabled && 'cursor-not-allowed', ...etc);
|
|
153
|
+
|
|
154
|
+
export const inputLabel: ComponentFunction<InputMetaStyleProps> = (props, ...etc) =>
|
|
155
|
+
mx('block', inputTextLabel, props.srOnly && 'sr-only', ...etc);
|
|
156
|
+
|
|
157
|
+
export const inputDescription: ComponentFunction<InputMetaStyleProps> = (props, ...etc) =>
|
|
158
|
+
mx(descriptionText, props.srOnly && 'sr-only', ...etc);
|
|
159
|
+
|
|
160
|
+
export const inputDescriptionAndValidation: ComponentFunction<InputMetaStyleProps> = (props, ...etc) =>
|
|
161
|
+
mx('leading-none mlb-labelSpacingBlock', props.srOnly && 'sr-only', ...etc);
|
|
162
|
+
|
|
163
|
+
export const inputValidation: ComponentFunction<InputMetaStyleProps> = (props, ...etc) =>
|
|
164
|
+
mx(descriptionText, props.srOnly ? 'sr-only' : valenceColorText(props.validationValence), ...etc);
|
|
165
|
+
|
|
166
|
+
export const inputTheme = {
|
|
167
|
+
input: inputInput,
|
|
168
|
+
inputWithSegments: inputWithSegmentsInput,
|
|
169
|
+
checkbox: inputCheckbox,
|
|
170
|
+
checkboxIndicator: inputCheckboxIndicator,
|
|
171
|
+
label: inputLabel,
|
|
172
|
+
description: inputDescription,
|
|
173
|
+
validation: inputValidation,
|
|
174
|
+
switch: inputSwitch,
|
|
175
|
+
switchThumb: inputSwitchThumb,
|
|
176
|
+
descriptionAndValidation: inputDescriptionAndValidation,
|
|
177
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComponentFunction, type Theme } from '@dxos/ui-types';
|
|
6
|
+
|
|
7
|
+
import { mx } from '../../util';
|
|
8
|
+
import { focusRing } from '../fragments';
|
|
9
|
+
|
|
10
|
+
export type LinkStyleProps = {
|
|
11
|
+
variant?: 'accent' | 'neutral';
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const linkRoot: ComponentFunction<LinkStyleProps> = ({ variant }, ...etc) =>
|
|
15
|
+
mx(
|
|
16
|
+
'underline decoration-1 underline-offset-2 transition-color rounded-sm',
|
|
17
|
+
variant === 'neutral'
|
|
18
|
+
? 'text-inherit hover:opacity-90 visited:text-inherit visited:hover:opacity-90'
|
|
19
|
+
: 'text-accentText hover:text-accentTextHover visited:text-accentText visited:hover:text-accentTextHover',
|
|
20
|
+
focusRing,
|
|
21
|
+
...etc,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
export const linkTheme: Theme<LinkStyleProps> = {
|
|
25
|
+
root: linkRoot,
|
|
26
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComponentFunction, type Density, type Theme } from '@dxos/ui-types';
|
|
6
|
+
|
|
7
|
+
import { mx } from '../../util';
|
|
8
|
+
import { densityBlockSize, focusRing, getSize, ghostHover } from '../fragments';
|
|
9
|
+
|
|
10
|
+
export type ListStyleProps = Partial<{
|
|
11
|
+
density: Density;
|
|
12
|
+
collapsible: boolean;
|
|
13
|
+
}>;
|
|
14
|
+
|
|
15
|
+
export const listRoot: ComponentFunction<ListStyleProps> = (_, ...etc) => mx(...etc);
|
|
16
|
+
|
|
17
|
+
export const listItem: ComponentFunction<ListStyleProps> = ({ collapsible }, ...etc) =>
|
|
18
|
+
mx(!collapsible && 'flex', ...etc);
|
|
19
|
+
|
|
20
|
+
export const listItemEndcap: ComponentFunction<ListStyleProps> = ({ density }, ...etc) =>
|
|
21
|
+
mx(density === 'fine' ? getSize(8) : getSize(10), 'shrink-0 flex items-center justify-center', ...etc);
|
|
22
|
+
|
|
23
|
+
export const listItemHeading: ComponentFunction<ListStyleProps> = ({ density }, ...etc) =>
|
|
24
|
+
mx(densityBlockSize(density), 'flex items-center', ...etc);
|
|
25
|
+
|
|
26
|
+
export const listItemDragHandleIcon: ComponentFunction<ListStyleProps> = (_props, ...etc) =>
|
|
27
|
+
mx(getSize(5), 'mbs-2.5', ...etc);
|
|
28
|
+
|
|
29
|
+
export const listItemOpenTrigger: ComponentFunction<ListStyleProps> = ({ density }, ...etc) =>
|
|
30
|
+
mx('is-5 rounded flex justify-center items-center', densityBlockSize(density), ghostHover, focusRing, ...etc);
|
|
31
|
+
|
|
32
|
+
export const listItemOpenTriggerIcon: ComponentFunction<ListStyleProps> = (_props, ...etc) => {
|
|
33
|
+
return mx(getSize(5), ...etc);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const listTheme: Theme<ListStyleProps> = {
|
|
37
|
+
root: listRoot,
|
|
38
|
+
item: {
|
|
39
|
+
root: listItem,
|
|
40
|
+
endcap: listItemEndcap,
|
|
41
|
+
heading: listItemHeading,
|
|
42
|
+
dragHandleIcon: listItemDragHandleIcon,
|
|
43
|
+
openTrigger: listItemOpenTrigger,
|
|
44
|
+
openTriggerIcon: listItemOpenTriggerIcon,
|
|
45
|
+
},
|
|
46
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComponentFunction } from '@dxos/ui-types';
|
|
6
|
+
|
|
7
|
+
import { mx } from '../../util';
|
|
8
|
+
|
|
9
|
+
// Padding to apply to in-flow elements which need to clear the fixed topbar / bottombar.
|
|
10
|
+
export const topbarBlockPaddingStart = 'pbs-[--topbar-size] sticky-top-from-topbar-bottom';
|
|
11
|
+
export const bottombarBlockPaddingEnd = 'pbe-[--statusbar-size] sticky-bottom-from-statusbar-bottom';
|
|
12
|
+
|
|
13
|
+
export type MainStyleProps = Partial<{
|
|
14
|
+
bounce: boolean;
|
|
15
|
+
handlesFocus: boolean;
|
|
16
|
+
}>;
|
|
17
|
+
|
|
18
|
+
export const mainSidebar: ComponentFunction<MainStyleProps> = (_, ...etc) =>
|
|
19
|
+
mx('dx-main-sidebar', 'dx-focus-ring-inset-over-all', ...etc);
|
|
20
|
+
|
|
21
|
+
export const mainPadding = 'dx-main-content-padding';
|
|
22
|
+
|
|
23
|
+
export const mainPaddingTransitions = 'dx-main-content-padding-transitions';
|
|
24
|
+
|
|
25
|
+
export const mainContent: ComponentFunction<MainStyleProps> = ({ bounce }, ...etc) =>
|
|
26
|
+
mx(mainPadding, mainPaddingTransitions, bounce && 'dx-main-bounce-layout', 'dx-focus-ring-main', ...etc);
|
|
27
|
+
|
|
28
|
+
export const mainIntrinsicSize = 'dx-main-intrinsic-size';
|
|
29
|
+
|
|
30
|
+
export const mainOverlay: ComponentFunction<MainStyleProps> = (_, ...etc) => mx('dx-main-overlay', ...etc);
|
|
31
|
+
|
|
32
|
+
export const mainTheme = {
|
|
33
|
+
content: mainContent,
|
|
34
|
+
sidebar: mainSidebar,
|
|
35
|
+
overlay: mainOverlay,
|
|
36
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComponentFunction, type Elevation, type Theme } from '@dxos/ui-types';
|
|
6
|
+
|
|
7
|
+
import { mx } from '../../util';
|
|
8
|
+
import {
|
|
9
|
+
dataDisabled,
|
|
10
|
+
descriptionText,
|
|
11
|
+
modalSurface,
|
|
12
|
+
popperMotion,
|
|
13
|
+
subduedFocus,
|
|
14
|
+
surfaceShadow,
|
|
15
|
+
surfaceZIndex,
|
|
16
|
+
} from '../fragments';
|
|
17
|
+
|
|
18
|
+
export type MenuStyleProps = Partial<{
|
|
19
|
+
constrainBlockSize: boolean;
|
|
20
|
+
elevation: Elevation;
|
|
21
|
+
}>;
|
|
22
|
+
|
|
23
|
+
export const menuViewport: ComponentFunction<MenuStyleProps> = (_props, ...etc) =>
|
|
24
|
+
mx('rounded p-1 max-bs-[--radix-dropdown-menu-content-available-height] overflow-y-auto', ...etc);
|
|
25
|
+
|
|
26
|
+
export const menuContent: ComponentFunction<MenuStyleProps> = ({ elevation }, ...etc) =>
|
|
27
|
+
mx(
|
|
28
|
+
'is-48 rounded md:is-56 border border-separator',
|
|
29
|
+
surfaceZIndex({ elevation, level: 'menu' }),
|
|
30
|
+
surfaceShadow({ elevation: 'positioned' }),
|
|
31
|
+
modalSurface,
|
|
32
|
+
popperMotion,
|
|
33
|
+
...etc,
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
export const menuItem: ComponentFunction<MenuStyleProps> = (_props, ...etc) =>
|
|
37
|
+
mx(
|
|
38
|
+
'flex cursor-pointer select-none items-center gap-2 rounded-sm pli-2 plb-2 text-sm',
|
|
39
|
+
'data-[highlighted]:bg-hoverSurface',
|
|
40
|
+
subduedFocus,
|
|
41
|
+
dataDisabled,
|
|
42
|
+
...etc,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
export const menuSeparator: ComponentFunction<MenuStyleProps> = (_props, ...etc) =>
|
|
46
|
+
mx('mlb-1 mli-2 bs-px bg-separator', ...etc);
|
|
47
|
+
|
|
48
|
+
export const menuGroupLabel: ComponentFunction<MenuStyleProps> = (_props, ...etc) =>
|
|
49
|
+
mx(descriptionText, 'select-none pli-2 plb-2', ...etc);
|
|
50
|
+
|
|
51
|
+
export const menuArrow: ComponentFunction<MenuStyleProps> = (_props, ...etc) => mx('fill-separator', ...etc);
|
|
52
|
+
|
|
53
|
+
export const menuTheme: Theme<MenuStyleProps> = {
|
|
54
|
+
content: menuContent,
|
|
55
|
+
viewport: menuViewport,
|
|
56
|
+
item: menuItem,
|
|
57
|
+
separator: menuSeparator,
|
|
58
|
+
groupLabel: menuGroupLabel,
|
|
59
|
+
arrow: menuArrow,
|
|
60
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComponentFunction, type Elevation, type MessageValence, type Theme } from '@dxos/ui-types';
|
|
6
|
+
|
|
7
|
+
import { mx } from '../../util';
|
|
8
|
+
import { messageValence } from '../fragments';
|
|
9
|
+
|
|
10
|
+
export type MessageStyleProps = {
|
|
11
|
+
valence?: MessageValence;
|
|
12
|
+
elevation?: Elevation;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const messageRoot: ComponentFunction<MessageStyleProps> = ({ valence }, etc) => {
|
|
16
|
+
return mx('p-trimSm rounded-md', messageValence(valence), etc);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const messageTitle: ComponentFunction<MessageStyleProps> = (_, etc) => {
|
|
20
|
+
return mx('font-medium flex gap-trimSm', etc);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const messageIcon: ComponentFunction<MessageStyleProps> = (_, etc) => {
|
|
24
|
+
return mx('flex bs-[1lh] items-center', etc);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const messageContent: ComponentFunction<MessageStyleProps> = (_, etc) => {
|
|
28
|
+
return mx('first:font-medium', etc);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const messageTheme: Theme<MessageStyleProps> = {
|
|
32
|
+
root: messageRoot,
|
|
33
|
+
content: messageContent,
|
|
34
|
+
icon: messageIcon,
|
|
35
|
+
title: messageTitle,
|
|
36
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComponentFunction, type Elevation, type Theme } from '@dxos/ui-types';
|
|
6
|
+
|
|
7
|
+
import { mx } from '../../util';
|
|
8
|
+
import { focusRing, modalSurface, surfaceShadow, surfaceZIndex } from '../fragments';
|
|
9
|
+
|
|
10
|
+
export type PopoverStyleProps = Partial<{
|
|
11
|
+
constrainBlock: boolean;
|
|
12
|
+
constrainInline: boolean;
|
|
13
|
+
elevation: Elevation;
|
|
14
|
+
}>;
|
|
15
|
+
|
|
16
|
+
export const popoverViewport: ComponentFunction<PopoverStyleProps> = ({ constrainBlock, constrainInline }, ...etc) =>
|
|
17
|
+
mx(
|
|
18
|
+
'rounded-md',
|
|
19
|
+
constrainBlock && 'max-bs-[--radix-popover-content-available-height] overflow-y-auto',
|
|
20
|
+
constrainInline && 'max-is-[--radix-popover-content-available-width] overflow-x-auto',
|
|
21
|
+
...etc,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
export const popoverContent: ComponentFunction<PopoverStyleProps> = ({ elevation }, ...etc) =>
|
|
25
|
+
mx(
|
|
26
|
+
'border border-separator rounded-md',
|
|
27
|
+
modalSurface,
|
|
28
|
+
surfaceShadow({ elevation: 'positioned' }),
|
|
29
|
+
surfaceZIndex({ elevation, level: 'menu' }),
|
|
30
|
+
focusRing,
|
|
31
|
+
...etc,
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
export const popoverArrow: ComponentFunction<PopoverStyleProps> = (_props, ...etc) => mx('fill-separator', ...etc);
|
|
35
|
+
|
|
36
|
+
export const popoverTheme: Theme<PopoverStyleProps> = {
|
|
37
|
+
content: popoverContent,
|
|
38
|
+
viewport: popoverViewport,
|
|
39
|
+
arrow: popoverArrow,
|
|
40
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComponentFunction, type Theme } from '@dxos/ui-types';
|
|
6
|
+
|
|
7
|
+
import { mx } from '../../util';
|
|
8
|
+
|
|
9
|
+
export type ScrollAreaStyleProps = {};
|
|
10
|
+
|
|
11
|
+
export const scrollAreaRoot: ComponentFunction<ScrollAreaStyleProps> = (_props, ...etc) =>
|
|
12
|
+
mx('__bs-full __is-full overflow-hidden', ...etc);
|
|
13
|
+
|
|
14
|
+
export const scrollAreaViewport: ComponentFunction<ScrollAreaStyleProps> = (_props, ...etc) =>
|
|
15
|
+
// mx('bs-full is-full [&>div]:is-full [&>div]:bs-auto', ...etc);
|
|
16
|
+
mx('bs-full is-full [&>div]:table-fixed [&>div]:is-full', ...etc);
|
|
17
|
+
|
|
18
|
+
export const scrollAreaScrollbar: ComponentFunction<ScrollAreaStyleProps> = (_props, ...etc) =>
|
|
19
|
+
mx(
|
|
20
|
+
'flex select-none touch-none p-0.5 ease-out',
|
|
21
|
+
'data-[orientation=vertical]:is-1.5 sm:data-[orientation=vertical]:data-[variant=coarse]:is-3',
|
|
22
|
+
'data-[orientation=horizontal]:flex-col data-[orientation=horizontal]:bs-1.5 sm:data-[orientation=horizontal]:data-[variant=coarse]:bs-3',
|
|
23
|
+
'sm:data-[variant=coarse]:bg-separator rounded-full',
|
|
24
|
+
'[&>div]:bg-unAccent sm:[&[data-variant=coarse]>div]:bg-attention',
|
|
25
|
+
...etc,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
export const scrollAreaThumb: ComponentFunction<ScrollAreaStyleProps> = (_props, ...etc) =>
|
|
29
|
+
mx(
|
|
30
|
+
'flex-1 rounded-full relative',
|
|
31
|
+
"before:content-[''] before:absolute before:top-1/2 before:left-1/2 before:-translate-x-1/2 before:-translate-y-1/2 before:is-full before:bs-full before:min-w-[6px] before:min-h-[6px]",
|
|
32
|
+
...etc,
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
export const scrollAreaCorner: ComponentFunction<ScrollAreaStyleProps> = (_props, ...etc) => mx(...etc);
|
|
36
|
+
|
|
37
|
+
export const scrollAreaTheme: Theme<ScrollAreaStyleProps> = {
|
|
38
|
+
root: scrollAreaRoot,
|
|
39
|
+
viewport: scrollAreaViewport,
|
|
40
|
+
scrollbar: scrollAreaScrollbar,
|
|
41
|
+
thumb: scrollAreaThumb,
|
|
42
|
+
corner: scrollAreaCorner,
|
|
43
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2022 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComponentFunction, type Elevation, type Theme } from '@dxos/ui-types';
|
|
6
|
+
|
|
7
|
+
import { mx } from '../../util';
|
|
8
|
+
import {
|
|
9
|
+
blockSeparator,
|
|
10
|
+
ghostHighlighted,
|
|
11
|
+
modalSurface,
|
|
12
|
+
separatorBorderColor,
|
|
13
|
+
surfaceShadow,
|
|
14
|
+
surfaceZIndex,
|
|
15
|
+
} from '../fragments';
|
|
16
|
+
|
|
17
|
+
export type SelectStyleProps = Partial<{
|
|
18
|
+
elevation: Elevation;
|
|
19
|
+
}>;
|
|
20
|
+
|
|
21
|
+
export const selectContent: ComponentFunction<SelectStyleProps> = ({ elevation }, ...etc) => {
|
|
22
|
+
return mx(
|
|
23
|
+
'min-w-[--radix-select-trigger-width] rounded max-bs-[--radix-select-content-available-height] border border-separator',
|
|
24
|
+
modalSurface,
|
|
25
|
+
surfaceShadow({ elevation: 'positioned' }),
|
|
26
|
+
surfaceZIndex({ elevation, level: 'menu' }),
|
|
27
|
+
...etc,
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const selectViewport: ComponentFunction<SelectStyleProps> = (_props, ...etc) => mx(...etc);
|
|
32
|
+
|
|
33
|
+
export const selectItem: ComponentFunction<SelectStyleProps> = (_props, ...etc) =>
|
|
34
|
+
mx(
|
|
35
|
+
'flex items-center min-bs-[2rem] pli-3 plb-1 gap-2',
|
|
36
|
+
'text-baseText leading-none select-none outline-none',
|
|
37
|
+
'[&>svg]:invisible [&[data-state=checked]>svg]:visible',
|
|
38
|
+
ghostHighlighted,
|
|
39
|
+
...etc,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
export const selectItemIndicator: ComponentFunction<SelectStyleProps> = (_props, ...etc) => mx('items-center', ...etc);
|
|
43
|
+
|
|
44
|
+
export const selectArrow: ComponentFunction<SelectStyleProps> = (_props, ...etc) => mx('fill-separator', ...etc);
|
|
45
|
+
|
|
46
|
+
export const selectSeparator: ComponentFunction<SelectStyleProps> = (_props, ...etc) =>
|
|
47
|
+
mx(blockSeparator, separatorBorderColor, ...etc);
|
|
48
|
+
|
|
49
|
+
export const selectScrollButton: ComponentFunction<SelectStyleProps> = (_props, ...etc) =>
|
|
50
|
+
mx(modalSurface, 'flex items-center justify-center cursor-default bs-6 is-full', ...etc);
|
|
51
|
+
|
|
52
|
+
export const selectTheme: Theme<SelectStyleProps> = {
|
|
53
|
+
content: selectContent,
|
|
54
|
+
viewport: selectViewport,
|
|
55
|
+
item: selectItem,
|
|
56
|
+
itemIndicator: selectItemIndicator,
|
|
57
|
+
arrow: selectArrow,
|
|
58
|
+
separator: selectSeparator,
|
|
59
|
+
scrollButton: selectScrollButton,
|
|
60
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComponentFunction, type Theme } from '@dxos/ui-types';
|
|
6
|
+
|
|
7
|
+
import { mx } from '../../util';
|
|
8
|
+
import { blockSeparator, inlineSeparator, separatorBorderColor, subduedSeparatorBorderColor } from '../fragments';
|
|
9
|
+
|
|
10
|
+
export type SeparatorStyleProps = {
|
|
11
|
+
orientation?: 'horizontal' | 'vertical';
|
|
12
|
+
subdued?: boolean;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const separatorRoot: ComponentFunction<SeparatorStyleProps> = ({ orientation, subdued }, ...etc) =>
|
|
16
|
+
mx(
|
|
17
|
+
orientation === 'vertical' ? inlineSeparator : blockSeparator,
|
|
18
|
+
subdued ? subduedSeparatorBorderColor : separatorBorderColor,
|
|
19
|
+
...etc,
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
export const separatorTheme: Theme<SeparatorStyleProps> = {
|
|
23
|
+
root: separatorRoot,
|
|
24
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import type { ComponentFunction, Theme } from '@dxos/ui-types';
|
|
6
|
+
|
|
7
|
+
import { mx } from '../../util';
|
|
8
|
+
|
|
9
|
+
export type StatusStyleProps = {
|
|
10
|
+
indeterminate?: boolean;
|
|
11
|
+
variant?: 'default' | 'main-bottom';
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const statusRoot: ComponentFunction<StatusStyleProps> = ({ variant = 'default' }, ...etc) =>
|
|
15
|
+
mx(
|
|
16
|
+
'bs-1 relative bg-hoverOverlay rounded-full overflow-hidden',
|
|
17
|
+
variant === 'main-bottom' ? 'is-full block' : 'is-20 inline-block',
|
|
18
|
+
...etc,
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export const statusBar: ComponentFunction<StatusStyleProps> = ({ indeterminate, variant = 'default' }, ...etc) =>
|
|
22
|
+
mx(
|
|
23
|
+
'absolute inset-block-0 block rounded-full',
|
|
24
|
+
variant === 'main-bottom' ? 'bg-accentSurface' : 'bg-unAccent',
|
|
25
|
+
indeterminate ? 'animate-progress-indeterminate' : 'inline-start-0',
|
|
26
|
+
...etc,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
export const statusTheme: Theme<StatusStyleProps> = {
|
|
30
|
+
root: statusRoot,
|
|
31
|
+
bar: statusBar,
|
|
32
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
type ChromaticPalette,
|
|
7
|
+
type ComponentFunction,
|
|
8
|
+
type MessageValence,
|
|
9
|
+
type NeutralPalette,
|
|
10
|
+
type Theme,
|
|
11
|
+
} from '@dxos/ui-types';
|
|
12
|
+
|
|
13
|
+
import { mx } from '../../util';
|
|
14
|
+
|
|
15
|
+
export type TagStyleProps = {
|
|
16
|
+
palette?: ChromaticPalette | NeutralPalette | MessageValence;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const tagRoot: ComponentFunction<TagStyleProps> = ({ palette = 'neutral' }, ...etc) => mx('dx-tag', ...etc);
|
|
20
|
+
|
|
21
|
+
export const tagTheme: Theme<TagStyleProps> = {
|
|
22
|
+
root: tagRoot,
|
|
23
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComponentFunction, type Theme } from '@dxos/ui-types';
|
|
6
|
+
|
|
7
|
+
import { mx } from '../../util';
|
|
8
|
+
import { descriptionText, focusRing, modalSurface, surfaceShadow } from '../fragments';
|
|
9
|
+
|
|
10
|
+
export type ToastStyleProps = Partial<{
|
|
11
|
+
srOnly: boolean;
|
|
12
|
+
}>;
|
|
13
|
+
|
|
14
|
+
export const toastViewport: ComponentFunction<ToastStyleProps> = (_props, ...etc) =>
|
|
15
|
+
mx(
|
|
16
|
+
// TODO(burdon): block-end should take into account status bar.
|
|
17
|
+
'z-40 fixed block-end-[calc(env(safe-area-inset-bottom)+1rem)] inset-start-[calc(env(safe-area-inset-left)+1rem)] inset-end-[calc(env(safe-area-inset-right)+1rem)] is-auto md:inline-end-[calc(env(safe-area-inset-right)+1rem)] md:inline-start-auto md:is-full md:max-is-sm',
|
|
18
|
+
'rounded-md flex flex-col gap-2',
|
|
19
|
+
...etc,
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
export const toastRoot: ComponentFunction<ToastStyleProps> = (_props, ...etc) =>
|
|
23
|
+
mx(
|
|
24
|
+
'rounded-md flex p-2 gap-2',
|
|
25
|
+
modalSurface,
|
|
26
|
+
surfaceShadow({ elevation: 'toast' }),
|
|
27
|
+
'radix-state-open:animate-toast-slide-in-bottom md:radix-state-open:animate-toast-slide-in-right',
|
|
28
|
+
'radix-state-closed:animate-toast-hide',
|
|
29
|
+
'radix-swipe-end:animate-toast-swipe-out',
|
|
30
|
+
'translate-x-radix-toast-swipe-move-x',
|
|
31
|
+
'radix-swipe-cancel:translate-x-0 radix-swipe-cancel:duration-200 radix-swipe-cancel:ease-[ease]',
|
|
32
|
+
focusRing,
|
|
33
|
+
...etc,
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
export const toastBody: ComponentFunction<ToastStyleProps> = (_props, ...etc) =>
|
|
37
|
+
mx('grow flex flex-col gap-1 justify-center pis-2', ...etc);
|
|
38
|
+
|
|
39
|
+
export const toastActions: ComponentFunction<ToastStyleProps> = (_props, ...etc) =>
|
|
40
|
+
mx('shrink-0 flex flex-col gap-1 justify-center', ...etc);
|
|
41
|
+
|
|
42
|
+
export const toastTitle: ComponentFunction<ToastStyleProps> = ({ srOnly }, ...etc) =>
|
|
43
|
+
mx('shrink-0 font-medium', srOnly && 'sr-only', ...etc);
|
|
44
|
+
|
|
45
|
+
export const toastDescription: ComponentFunction<ToastStyleProps> = ({ srOnly }, ...etc) =>
|
|
46
|
+
mx(descriptionText, 'shrink-0', srOnly && 'sr-only', ...etc);
|
|
47
|
+
|
|
48
|
+
export const toastTheme: Theme<ToastStyleProps> = {
|
|
49
|
+
viewport: toastViewport,
|
|
50
|
+
root: toastRoot,
|
|
51
|
+
body: toastBody,
|
|
52
|
+
title: toastTitle,
|
|
53
|
+
description: toastDescription,
|
|
54
|
+
actions: toastActions,
|
|
55
|
+
};
|