@getcortexlabs/mavis-core 0.1.0-alpha.1 → 0.1.0-alpha.2
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/README.md +2 -2
- package/dist/icon.d.ts +15 -0
- package/dist/icon.d.ts.map +1 -0
- package/dist/icon.js +28 -0
- package/dist/icon.js.map +1 -0
- package/dist/icons.d.ts +2002 -0
- package/dist/icons.d.ts.map +1 -0
- package/dist/icons.js +2003 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/vue/global-components.d.ts +1 -0
- package/dist/vue/global-components.d.ts.map +1 -1
- package/dist/vue/index.d.ts +2 -2
- package/dist/vue/index.d.ts.map +1 -1
- package/dist/vue/index.js +1 -1
- package/dist/vue/index.js.map +1 -1
- package/dist/vue/props.d.ts +101 -18
- package/dist/vue/props.d.ts.map +1 -1
- package/dist/vue/props.js +35 -16
- package/dist/vue/props.js.map +1 -1
- package/dist/vue/theme.d.ts +25 -7
- package/dist/vue/theme.d.ts.map +1 -1
- package/dist/vue/theme.js +37 -2
- package/dist/vue/theme.js.map +1 -1
- package/package.json +1 -1
- package/src/icon.ts +30 -0
- package/src/icons.ts +2002 -0
- package/src/index.ts +3 -0
- package/src/vue/global-components.ts +1 -0
- package/src/vue/index.ts +8 -1
- package/src/vue/props.ts +35 -19
- package/src/vue/theme.ts +54 -3
package/src/index.ts
CHANGED
|
@@ -16,4 +16,7 @@ export { sliderScale } from './slider.js'
|
|
|
16
16
|
export { resolveDimension, resolveRadius, nonNegative } from './layout.js'
|
|
17
17
|
export type { Dimension } from './layout.js'
|
|
18
18
|
export { validateInput } from './input.js'
|
|
19
|
+
export { icons, iconFontVersion } from './icons.js'
|
|
20
|
+
export { iconGlyph, iconFontFamily, iconSizes, resolveIconSize, checkIconOnly } from './icon.js'
|
|
21
|
+
export type { IconName, IconSize } from './icon.js'
|
|
19
22
|
export type { InputHandle } from './input.js'
|
|
@@ -22,6 +22,7 @@ declare module '@vue/runtime-core' {
|
|
|
22
22
|
MButton: DefineComponent<ComponentProps['MButton'] & Action>
|
|
23
23
|
MSlider: DefineComponent<ComponentProps['MSlider'] & Model>
|
|
24
24
|
MInput: DefineComponent<ComponentProps['MInput'] & InputEvents>
|
|
25
|
+
MIcon: DefineComponent<ComponentProps['MIcon']>
|
|
25
26
|
MReveal: DefineComponent<ComponentProps['MReveal']>
|
|
26
27
|
}
|
|
27
28
|
}
|
package/src/vue/index.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
export { createThemeContext, themeKey, useMavisTheme } from './theme.js'
|
|
2
|
-
export type {
|
|
2
|
+
export type {
|
|
3
|
+
MavisThemeContext,
|
|
4
|
+
Appearance,
|
|
5
|
+
AppearanceMode,
|
|
6
|
+
AppearanceSource,
|
|
7
|
+
ThemeContextOptions,
|
|
8
|
+
} from './theme.js'
|
|
3
9
|
export { layoutDirection, useDefaultShrink } from './layout-context.js'
|
|
4
10
|
export { textContent } from './text-content.js'
|
|
5
11
|
export type {} from './global-components.js'
|
|
@@ -14,6 +20,7 @@ export {
|
|
|
14
20
|
sliderProps,
|
|
15
21
|
inputProps,
|
|
16
22
|
inputEmits,
|
|
23
|
+
iconProps,
|
|
17
24
|
screenProps,
|
|
18
25
|
revealProps,
|
|
19
26
|
componentProps,
|
package/src/vue/props.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ExtractPropTypes, ExtractPublicPropTypes, PropType } from '@vue/runtime-core'
|
|
2
2
|
import type { Palette, Spacing, Radius } from '../theme/types.js'
|
|
3
3
|
import type { Dimension } from '../layout.js'
|
|
4
|
+
import { iconSizes, type IconName, type IconSize } from '../icon.js'
|
|
4
5
|
|
|
5
6
|
function choice<T extends string>(values: readonly T[], defaultValue: T) {
|
|
6
7
|
return {
|
|
@@ -77,32 +78,32 @@ export const buttonProps = {
|
|
|
77
78
|
disabled: Boolean,
|
|
78
79
|
loading: Boolean,
|
|
79
80
|
loadingText: { type: String, default: 'Loading…' },
|
|
81
|
+
icon: { type: String as PropType<IconName>, default: undefined },
|
|
82
|
+
trailingIcon: { type: String as PropType<IconName>, default: undefined },
|
|
80
83
|
}
|
|
84
|
+
const tones: readonly (keyof Palette)[] = [
|
|
85
|
+
'background',
|
|
86
|
+
'surface',
|
|
87
|
+
'elevated',
|
|
88
|
+
'text',
|
|
89
|
+
'muted',
|
|
90
|
+
'primary',
|
|
91
|
+
'onPrimary',
|
|
92
|
+
'primarySoft',
|
|
93
|
+
'accent',
|
|
94
|
+
'onAccent',
|
|
95
|
+
'accentSoft',
|
|
96
|
+
'border',
|
|
97
|
+
'success',
|
|
98
|
+
'danger',
|
|
99
|
+
]
|
|
81
100
|
export const textProps = {
|
|
82
101
|
...viewProps,
|
|
83
102
|
...flexProps,
|
|
84
103
|
text: { type: String, default: undefined },
|
|
85
104
|
as: choice(['p', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as const, 'p'),
|
|
86
105
|
variant: choice(['display', 'title', 'heading', 'body', 'caption', 'overline'] as const, 'body'),
|
|
87
|
-
tone: choice<keyof Palette>(
|
|
88
|
-
[
|
|
89
|
-
'background',
|
|
90
|
-
'surface',
|
|
91
|
-
'elevated',
|
|
92
|
-
'text',
|
|
93
|
-
'muted',
|
|
94
|
-
'primary',
|
|
95
|
-
'onPrimary',
|
|
96
|
-
'primarySoft',
|
|
97
|
-
'accent',
|
|
98
|
-
'onAccent',
|
|
99
|
-
'accentSoft',
|
|
100
|
-
'border',
|
|
101
|
-
'success',
|
|
102
|
-
'danger',
|
|
103
|
-
],
|
|
104
|
-
'text',
|
|
105
|
-
),
|
|
106
|
+
tone: choice<keyof Palette>(tones, 'text'),
|
|
106
107
|
align: choice(['left', 'center', 'right'] as const, 'left'),
|
|
107
108
|
wrap: { type: Boolean, default: true },
|
|
108
109
|
}
|
|
@@ -139,6 +140,8 @@ export const inputProps = {
|
|
|
139
140
|
},
|
|
140
141
|
autocorrect: { type: Boolean, default: undefined },
|
|
141
142
|
returnKey: choice(['done', 'next', 'go', 'search', 'send'] as const, 'done'),
|
|
143
|
+
icon: { type: String as PropType<IconName>, default: undefined },
|
|
144
|
+
trailingIcon: { type: String as PropType<IconName>, default: undefined },
|
|
142
145
|
}
|
|
143
146
|
export const inputEmits = {
|
|
144
147
|
'update:modelValue': (value: string) => typeof value === 'string',
|
|
@@ -146,6 +149,18 @@ export const inputEmits = {
|
|
|
146
149
|
blur: () => true,
|
|
147
150
|
submit: (value: string) => typeof value === 'string',
|
|
148
151
|
}
|
|
152
|
+
export const iconProps = {
|
|
153
|
+
id: viewProps.id,
|
|
154
|
+
name: { type: String as PropType<IconName>, required: true as const },
|
|
155
|
+
size: {
|
|
156
|
+
type: [String, Number] as PropType<IconSize>,
|
|
157
|
+
default: 'md',
|
|
158
|
+
validator: (value: IconSize) => typeof value === 'number' || value in iconSizes,
|
|
159
|
+
},
|
|
160
|
+
tone: choice<keyof Palette>(tones, 'text'),
|
|
161
|
+
/** Accessible name. Without it the icon is decorative and hidden from assistive technology. */
|
|
162
|
+
label: { type: String, default: undefined },
|
|
163
|
+
}
|
|
149
164
|
export const screenProps = { ...viewProps, scroll: Boolean }
|
|
150
165
|
export const revealProps = { ...columnProps, show: Boolean }
|
|
151
166
|
export const actionEmits = { click: () => true }
|
|
@@ -161,6 +176,7 @@ export const componentProps = {
|
|
|
161
176
|
MButton: buttonProps,
|
|
162
177
|
MSlider: sliderProps,
|
|
163
178
|
MInput: inputProps,
|
|
179
|
+
MIcon: iconProps,
|
|
164
180
|
MReveal: revealProps,
|
|
165
181
|
}
|
|
166
182
|
export type BoxProps = ExtractPropTypes<typeof boxProps>
|
package/src/vue/theme.ts
CHANGED
|
@@ -2,17 +2,68 @@ import { inject, readonly, shallowRef, type InjectionKey } from '@vue/runtime-co
|
|
|
2
2
|
import { mavis } from '../theme/themes.js'
|
|
3
3
|
import type { MavisTheme } from '../theme/types.js'
|
|
4
4
|
|
|
5
|
-
export
|
|
5
|
+
export type Appearance = MavisTheme['appearance']
|
|
6
|
+
export type AppearanceMode = Appearance | 'system'
|
|
7
|
+
|
|
8
|
+
/** Platform access to the device appearance; `current` is undefined while it is unknown, such as during SSR. */
|
|
9
|
+
export interface AppearanceSource {
|
|
10
|
+
current(): Appearance | undefined
|
|
11
|
+
observe(listener: (appearance: Appearance) => void): () => void
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ThemeContextOptions {
|
|
15
|
+
theme?: MavisTheme
|
|
16
|
+
darkTheme?: MavisTheme
|
|
17
|
+
appearance?: AppearanceMode
|
|
18
|
+
source?: AppearanceSource
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const modes: readonly AppearanceMode[] = ['system', 'light', 'dark']
|
|
22
|
+
|
|
23
|
+
function checkMode(mode: AppearanceMode) {
|
|
24
|
+
if (!modes.includes(mode)) throw new RangeError(`Unknown appearance mode: ${String(mode)}`)
|
|
25
|
+
return mode
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function createThemeContext(options: MavisTheme | ThemeContextOptions = {}) {
|
|
29
|
+
const config: ThemeContextOptions = 'colors' in options ? { theme: options } : options
|
|
30
|
+
const initial = config.theme ?? mavis
|
|
31
|
+
const themes: Partial<Record<Appearance, MavisTheme>> = { [initial.appearance]: initial }
|
|
32
|
+
if (config.darkTheme) themes.dark = config.darkTheme
|
|
33
|
+
const appearance = shallowRef(checkMode(config.appearance ?? 'system'))
|
|
6
34
|
const theme = shallowRef(initial)
|
|
35
|
+
const resolve = () => {
|
|
36
|
+
const wanted =
|
|
37
|
+
appearance.value === 'system'
|
|
38
|
+
? (config.source?.current() ?? initial.appearance)
|
|
39
|
+
: appearance.value
|
|
40
|
+
theme.value = themes[wanted] ?? themes[wanted === 'dark' ? 'light' : 'dark'] ?? initial
|
|
41
|
+
}
|
|
42
|
+
resolve()
|
|
43
|
+
const stop = config.source?.observe(() => {
|
|
44
|
+
if (appearance.value === 'system') resolve()
|
|
45
|
+
})
|
|
7
46
|
return {
|
|
8
47
|
theme: readonly(theme),
|
|
48
|
+
/** The selection: `system` follows the device; `light` and `dark` are explicit overrides. */
|
|
49
|
+
appearance: readonly(appearance),
|
|
50
|
+
setAppearance(mode: AppearanceMode) {
|
|
51
|
+
appearance.value = checkMode(mode)
|
|
52
|
+
resolve()
|
|
53
|
+
},
|
|
54
|
+
/** Registers the theme for its own appearance and pins that appearance. */
|
|
9
55
|
setTheme(next: MavisTheme) {
|
|
10
|
-
|
|
56
|
+
themes[next.appearance] = next
|
|
57
|
+
appearance.value = next.appearance
|
|
58
|
+
resolve()
|
|
59
|
+
},
|
|
60
|
+
dispose() {
|
|
61
|
+
stop?.()
|
|
11
62
|
},
|
|
12
63
|
}
|
|
13
64
|
}
|
|
14
|
-
|
|
15
65
|
export type MavisThemeContext = ReturnType<typeof createThemeContext>
|
|
66
|
+
|
|
16
67
|
export const themeKey: InjectionKey<MavisThemeContext> = Symbol('mavis.theme')
|
|
17
68
|
|
|
18
69
|
/** Without the plugin, individually imported components use the default theme. */
|