vuetiwatch 0.2.0 → 0.2.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 +25 -202
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +19 -3
- package/dist/plugin.js.map +1 -1
- package/dist/styles/aurora.css +1 -1
- package/dist/styles/aurora.min.css +1 -1
- package/dist/styles/brutalist.css +1 -1
- package/dist/styles/brutalist.min.css +1 -1
- package/dist/styles/calm.css +1 -1
- package/dist/styles/calm.min.css +1 -1
- package/dist/styles/candy.css +1 -4
- package/dist/styles/candy.min.css +1 -1
- package/dist/styles/clay.css +1 -1
- package/dist/styles/clay.min.css +1 -1
- package/dist/styles/core.css +44 -2
- package/dist/styles/core.min.css +1 -1
- package/dist/styles/darkGlass.css +1 -1
- package/dist/styles/darkGlass.min.css +1 -1
- package/dist/styles/liquidGlass.css +10 -1
- package/dist/styles/liquidGlass.min.css +1 -1
- package/dist/styles/lux.css +1 -1
- package/dist/styles/lux.min.css +1 -1
- package/dist/styles/neon.css +1 -1
- package/dist/styles/neon.min.css +1 -1
- package/dist/styles/slate.css +1 -1
- package/dist/styles/slate.min.css +1 -1
- package/dist/styles/soft.css +3 -2
- package/dist/styles/soft.min.css +1 -1
- package/dist/styles.css +66 -17
- package/dist/styles.min.css +1 -1
- package/dist/themes/atlas.d.ts +35 -0
- package/dist/themes/atlas.d.ts.map +1 -1
- package/dist/themes/atlas.js +75 -1
- package/dist/themes/atlas.js.map +1 -1
- package/dist/themes/atlasDark.d.ts.map +1 -1
- package/dist/themes/atlasDark.js +5 -0
- package/dist/themes/atlasDark.js.map +1 -1
- package/dist/themes/atlasSepia.d.ts.map +1 -1
- package/dist/themes/atlasSepia.js +5 -0
- package/dist/themes/atlasSepia.js.map +1 -1
- package/dist/themes/aurora.d.ts.map +1 -1
- package/dist/themes/aurora.js +20 -1
- package/dist/themes/aurora.js.map +1 -1
- package/dist/themes/brutalist.d.ts.map +1 -1
- package/dist/themes/brutalist.js +63 -5
- package/dist/themes/brutalist.js.map +1 -1
- package/dist/themes/calm.d.ts.map +1 -1
- package/dist/themes/calm.js +22 -1
- package/dist/themes/calm.js.map +1 -1
- package/dist/themes/candy.d.ts.map +1 -1
- package/dist/themes/candy.js +23 -1
- package/dist/themes/candy.js.map +1 -1
- package/dist/themes/clay.d.ts.map +1 -1
- package/dist/themes/clay.js +14 -1
- package/dist/themes/clay.js.map +1 -1
- package/dist/themes/darkGlass.d.ts.map +1 -1
- package/dist/themes/darkGlass.js +13 -1
- package/dist/themes/darkGlass.js.map +1 -1
- package/dist/themes/graphite.d.ts.map +1 -1
- package/dist/themes/graphite.js +42 -7
- package/dist/themes/graphite.js.map +1 -1
- package/dist/themes/liquidGlass.d.ts.map +1 -1
- package/dist/themes/liquidGlass.js +41 -5
- package/dist/themes/liquidGlass.js.map +1 -1
- package/dist/themes/lux.d.ts.map +1 -1
- package/dist/themes/lux.js +48 -6
- package/dist/themes/lux.js.map +1 -1
- package/dist/themes/morph.d.ts.map +1 -1
- package/dist/themes/morph.js +21 -1
- package/dist/themes/morph.js.map +1 -1
- package/dist/themes/neon.d.ts.map +1 -1
- package/dist/themes/neon.js +35 -1
- package/dist/themes/neon.js.map +1 -1
- package/dist/themes/paper.d.ts.map +1 -1
- package/dist/themes/paper.js +38 -1
- package/dist/themes/paper.js.map +1 -1
- package/dist/themes/sketchy.d.ts.map +1 -1
- package/dist/themes/sketchy.js +27 -1
- package/dist/themes/sketchy.js.map +1 -1
- package/dist/themes/slate.d.ts.map +1 -1
- package/dist/themes/slate.js +42 -6
- package/dist/themes/slate.js.map +1 -1
- package/dist/themes/soft.d.ts.map +1 -1
- package/dist/themes/soft.js +49 -8
- package/dist/themes/soft.js.map +1 -1
- package/dist/util/defaults.d.ts +35 -0
- package/dist/util/defaults.d.ts.map +1 -1
- package/dist/util/defaults.js +51 -0
- package/dist/util/defaults.js.map +1 -1
- package/package.json +2 -1
- package/src/index.ts +2 -2
- package/src/plugin.ts +20 -3
- package/src/styles/core.css +152 -3
- package/src/styles/themes/aurora.css +1 -0
- package/src/styles/themes/brutalist.css +1 -0
- package/src/styles/themes/calm.css +1 -0
- package/src/styles/themes/candy.css +9 -4
- package/src/styles/themes/clay.css +1 -0
- package/src/styles/themes/darkGlass.css +1 -0
- package/src/styles/themes/liquidGlass.css +41 -0
- package/src/styles/themes/lux.css +1 -0
- package/src/styles/themes/neon.css +1 -0
- package/src/styles/themes/slate.css +1 -0
- package/src/styles/themes/soft.css +10 -0
- package/src/themes/atlas.ts +76 -1
- package/src/themes/atlasDark.ts +5 -0
- package/src/themes/atlasSepia.ts +5 -0
- package/src/themes/aurora.ts +21 -1
- package/src/themes/brutalist.ts +65 -5
- package/src/themes/calm.ts +23 -1
- package/src/themes/candy.ts +24 -1
- package/src/themes/clay.ts +15 -1
- package/src/themes/darkGlass.ts +14 -1
- package/src/themes/graphite.ts +44 -7
- package/src/themes/liquidGlass.ts +42 -5
- package/src/themes/lux.ts +50 -6
- package/src/themes/morph.ts +22 -1
- package/src/themes/neon.ts +37 -1
- package/src/themes/paper.ts +40 -1
- package/src/themes/sketchy.ts +29 -1
- package/src/themes/slate.ts +43 -6
- package/src/themes/soft.ts +50 -8
- package/src/util/defaults.ts +84 -0
package/src/themes/slate.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bars, controls, fields, icons, tables } from '../util/defaults.js'
|
|
1
|
+
import { bars, controls, fields, icons, overlays, ripple, tables } from '../util/defaults.js'
|
|
2
2
|
import { defineTheme } from '../util/defineTheme.js'
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -32,13 +32,24 @@ export const slate = defineTheme({
|
|
|
32
32
|
error: '#C53030',
|
|
33
33
|
info: '#2B6CB0',
|
|
34
34
|
success: '#2F855A',
|
|
35
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Deepened rather than re-inked. Vuetify picks the label colour by
|
|
37
|
+
* APCA and settles for about 3:1 on WCAG, which is the bar for large
|
|
38
|
+
* text rather than for a button label — so this theme states `on-*`
|
|
39
|
+
* wherever the automatic pick falls short.
|
|
40
|
+
*
|
|
41
|
+
* Warning is the case where doing that made things worse. The ochre
|
|
42
|
+
* sat where WCAG wanted black and APCA wanted white by a wide margin
|
|
43
|
+
* (71 to 39), and the forced dark label did not even clear 4.5:1
|
|
44
|
+
* (4.48:1). Taking 12 per cent of lightness out of the hue satisfies both:
|
|
45
|
+
* white now reads 4.53:1 on the filled button, APCA 79, and the colour
|
|
46
|
+
* as text on the surface goes from 3.64:1 — under the bar it was
|
|
47
|
+
* being held to elsewhere — to 4.53:1. The label is left to the
|
|
48
|
+
* automatic pick, which is white.
|
|
49
|
+
*/
|
|
50
|
+
warning: '#A16B1B',
|
|
36
51
|
'on-surface': '#1A202C',
|
|
37
52
|
'on-background': '#1A202C',
|
|
38
|
-
// Vuetify picks the label colour by luminance and settles for
|
|
39
|
-
// about 3:1, which is the bar for large text rather than for a
|
|
40
|
-
// button label. Measured on the filled buttons: warning 3.6:1 → 4.5:1.
|
|
41
|
-
'on-warning': '#1A202C',
|
|
42
53
|
},
|
|
43
54
|
variables: {
|
|
44
55
|
/* A panel standing on its own — a bare list, sheet, banner or table.
|
|
@@ -72,6 +83,20 @@ export const slate = defineTheme({
|
|
|
72
83
|
'vw-pop-duration': '160ms',
|
|
73
84
|
'vw-focus-ring': '2px solid rgb(var(--v-theme-primary))',
|
|
74
85
|
|
|
86
|
+
// The dashboard's own tempo, applied to the panels that float over it.
|
|
87
|
+
'vw-overlay-duration': '120ms',
|
|
88
|
+
'vw-overlay-exit': '90ms',
|
|
89
|
+
// The focus ring above carries the keyboard; the wash only has to not
|
|
90
|
+
// fight it. The active row, though, has to be findable in a table of
|
|
91
|
+
// a hundred.
|
|
92
|
+
'focus-opacity': 0.12,
|
|
93
|
+
'activated-opacity': 0.12,
|
|
94
|
+
'disabled-opacity': 0.42,
|
|
95
|
+
'theme-code': '#EAEEF3',
|
|
96
|
+
'theme-on-code': '#1A202C',
|
|
97
|
+
'theme-kbd': '#EAEEF3',
|
|
98
|
+
'theme-on-kbd': '#1A202C',
|
|
99
|
+
|
|
75
100
|
// Dense and structural: a 2px rule and a square dot.
|
|
76
101
|
'vw-timeline-line': 'rgba(var(--v-theme-primary), 0.35)',
|
|
77
102
|
'vw-timeline-line-width': '2px',
|
|
@@ -109,5 +134,17 @@ export const slate = defineTheme({
|
|
|
109
134
|
sortAsc: 'mdi-menu-up',
|
|
110
135
|
sortDesc: 'mdi-menu-down',
|
|
111
136
|
}),
|
|
137
|
+
/**
|
|
138
|
+
* A dropdown drops. Everything else fades: a dialog over a dashboard is
|
|
139
|
+
* a change of subject, not an entrance, and the data behind it should
|
|
140
|
+
* not be dragged around while it arrives.
|
|
141
|
+
*/
|
|
142
|
+
overlays({
|
|
143
|
+
dialog: 'fade-transition',
|
|
144
|
+
menu: 'slide-y-transition',
|
|
145
|
+
tooltip: 'fade-transition',
|
|
146
|
+
}),
|
|
147
|
+
// Dense rows and a spreading ink blot do not go together.
|
|
148
|
+
ripple(false),
|
|
112
149
|
],
|
|
113
150
|
})
|
package/src/themes/soft.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bars, fields, icons } from '../util/defaults.js'
|
|
1
|
+
import { bars, fields, icons, overlays } from '../util/defaults.js'
|
|
2
2
|
import { defineTheme } from '../util/defineTheme.js'
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -35,13 +35,35 @@ export const soft = defineTheme({
|
|
|
35
35
|
warning: '#F5B851',
|
|
36
36
|
'on-surface': '#2E2A3B',
|
|
37
37
|
'on-background': '#2E2A3B',
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
/**
|
|
39
|
+
* The one stated exception in the package, and it is deliberate.
|
|
40
|
+
*
|
|
41
|
+
* White on these pastels does not clear WCAG's 4.5:1 for a button
|
|
42
|
+
* label: secondary 2.33:1, error 2.84:1, info 2.25:1, success 2.21:1,
|
|
43
|
+
* warning 1.77:1. The dark ink that white replaced carried 4.89:1 to
|
|
44
|
+
* 11.86:1, and APCA agrees with WCAG on every one of them — so this
|
|
45
|
+
* is not a case of the two models disagreeing and a hue needing a few
|
|
46
|
+
* points of lightness, which is how every other theme here resolves
|
|
47
|
+
* it. The only arrangement that gets white over the bar takes these
|
|
48
|
+
* hues down 23 to 39 per cent, and a pastel darkened by a third is
|
|
49
|
+
* not a pastel: it would be a different theme wearing this one's name.
|
|
50
|
+
*
|
|
51
|
+
* So the trade is made the other way round, once, in the theme whose
|
|
52
|
+
* whole proposition is softness — and it is a trade, not an oversight.
|
|
53
|
+
* A screen that has to be read by everyone should reach for a theme
|
|
54
|
+
* that measures; `atlas` and `graphite` exist for that, and `soft` is
|
|
55
|
+
* for the onboarding flow and the marketing page where the palette is
|
|
56
|
+
* the point. `docs/contrast.md` says as much next to the claim it
|
|
57
|
+
* qualifies.
|
|
58
|
+
*
|
|
59
|
+
* `primary` is not listed because it needs no help: at #705EEF white
|
|
60
|
+
* already reads 4.63:1 and is the automatic pick.
|
|
61
|
+
*/
|
|
62
|
+
'on-secondary': '#FFFFFF',
|
|
63
|
+
'on-error': '#FFFFFF',
|
|
64
|
+
'on-info': '#FFFFFF',
|
|
65
|
+
'on-success': '#FFFFFF',
|
|
66
|
+
'on-warning': '#FFFFFF',
|
|
45
67
|
},
|
|
46
68
|
variables: {
|
|
47
69
|
/* A panel standing on its own — a bare list, sheet, banner or table.
|
|
@@ -69,6 +91,16 @@ export const soft = defineTheme({
|
|
|
69
91
|
'vw-pop-scale': '1.22',
|
|
70
92
|
'vw-pop-duration': '260ms',
|
|
71
93
|
|
|
94
|
+
// Unhurried here as well, with the exit a touch quicker so a
|
|
95
|
+
// dismissed panel does not linger.
|
|
96
|
+
'vw-overlay-duration': '250ms',
|
|
97
|
+
'vw-overlay-exit': '180ms',
|
|
98
|
+
// Tonal fills are this theme's colour, so they are drawn to be seen.
|
|
99
|
+
'focus-opacity': 0.14,
|
|
100
|
+
'activated-opacity': 0.14,
|
|
101
|
+
// Bigger initials inside the circle, to match everything else here.
|
|
102
|
+
'vw-avatar-ratio': '0.44',
|
|
103
|
+
|
|
72
104
|
// Thick and pastel, matching the radii.
|
|
73
105
|
'vw-timeline-line': 'rgba(var(--v-theme-primary), 0.25)',
|
|
74
106
|
'vw-timeline-line-width': '5px',
|
|
@@ -102,5 +134,15 @@ export const soft = defineTheme({
|
|
|
102
134
|
ratingEmpty: 'mdi-heart-outline',
|
|
103
135
|
close: 'mdi-close-circle',
|
|
104
136
|
}),
|
|
137
|
+
/**
|
|
138
|
+
* Friendly rather than efficient: a dialog swells into place, a menu
|
|
139
|
+
* drops from the control that opened it. The ripple stays — this is one
|
|
140
|
+
* of the themes with a surface soft enough to justify it.
|
|
141
|
+
*/
|
|
142
|
+
overlays({
|
|
143
|
+
dialog: 'scale-transition',
|
|
144
|
+
menu: 'slide-y-transition',
|
|
145
|
+
tooltip: 'scale-transition',
|
|
146
|
+
}),
|
|
105
147
|
],
|
|
106
148
|
})
|
package/src/util/defaults.ts
CHANGED
|
@@ -38,6 +38,36 @@ const CONTROL_COMPONENTS = [
|
|
|
38
38
|
'VSwitch',
|
|
39
39
|
] as const
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Everything that draws a Material ripple.
|
|
43
|
+
*
|
|
44
|
+
* Longer than it looks, because a defaults key is matched by component
|
|
45
|
+
* name and several of these only look like a `VBtn`. The tab, the app-bar
|
|
46
|
+
* nav icon and the fab each declare their own prop set and hand it to a
|
|
47
|
+
* `VBtn` themselves, so a `VBtn` default never reaches them; the checkbox,
|
|
48
|
+
* the radio and the switch all reach one `VSelectionControl` underneath
|
|
49
|
+
* but arrive there under three different names. A theme that turned the
|
|
50
|
+
* ripple off on buttons alone would still get one from the hamburger and
|
|
51
|
+
* from every tick box on the screen.
|
|
52
|
+
*/
|
|
53
|
+
const RIPPLE_COMPONENTS = [
|
|
54
|
+
'VBtn',
|
|
55
|
+
'VTab',
|
|
56
|
+
'VAppBarNavIcon',
|
|
57
|
+
'VFab',
|
|
58
|
+
'VChip',
|
|
59
|
+
'VCard',
|
|
60
|
+
'VListItem',
|
|
61
|
+
'VExpansionPanelTitle',
|
|
62
|
+
'VStepperItem',
|
|
63
|
+
'VRating',
|
|
64
|
+
'VCheckbox',
|
|
65
|
+
'VCheckboxBtn',
|
|
66
|
+
'VRadio',
|
|
67
|
+
'VRadioGroup',
|
|
68
|
+
'VSwitch',
|
|
69
|
+
] as const
|
|
70
|
+
|
|
41
71
|
/** Containers that share the `flat` / `border` props. */
|
|
42
72
|
const BAR_COMPONENTS = [
|
|
43
73
|
'VAppBar',
|
|
@@ -73,6 +103,60 @@ export const bars = (props: Props): VuetiwatchDefaults =>
|
|
|
73
103
|
export const surfaces = (props: Props): VuetiwatchDefaults =>
|
|
74
104
|
spread(SURFACE_COMPONENTS, props)
|
|
75
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Turns the Material ripple off — or back on — everywhere one is drawn.
|
|
108
|
+
*
|
|
109
|
+
* The ripple is an animation about the weight of a surface, so a theme
|
|
110
|
+
* with no weight to describe is better off without it: it delays the
|
|
111
|
+
* moment a control looks like it answered, which on a screen someone
|
|
112
|
+
* works in all day is the one thing motion must never do.
|
|
113
|
+
*/
|
|
114
|
+
export const ripple = (on: boolean): VuetiwatchDefaults =>
|
|
115
|
+
spread(RIPPLE_COMPONENTS, { ripple: on })
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* How each floating surface arrives.
|
|
119
|
+
*
|
|
120
|
+
* Vuetify names its transitions and resolves them from a string, so this
|
|
121
|
+
* is an ordinary prop like any other — which is what lets a theme own its
|
|
122
|
+
* overlays as well as its colours. `false` means no animation at all: the
|
|
123
|
+
* surface is simply there, which is the honest answer for a theme that
|
|
124
|
+
* draws no depth to move through.
|
|
125
|
+
*
|
|
126
|
+
* `menu` reaches the select, the autocomplete and the combobox as well,
|
|
127
|
+
* but not by one route: autocomplete and combobox let the `VMenu` they
|
|
128
|
+
* render take the global default, while `VSelect` declares a `transition`
|
|
129
|
+
* prop of its own and hands it down, which shadows that default entirely.
|
|
130
|
+
* So the select is named here too, and a theme still states its menus once.
|
|
131
|
+
*/
|
|
132
|
+
export interface VuetiwatchOverlays {
|
|
133
|
+
/** A modal. Vuetify's own is `dialog-transition`. */
|
|
134
|
+
dialog?: string | false
|
|
135
|
+
/** A dropdown, a select's list, a context menu. */
|
|
136
|
+
menu?: string | false
|
|
137
|
+
/** A tooltip. Vuetify scales it in and fades it out. */
|
|
138
|
+
tooltip?: string | false
|
|
139
|
+
/** A snackbar. */
|
|
140
|
+
snackbar?: string | false
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function overlays (set: VuetiwatchOverlays): VuetiwatchDefaults {
|
|
144
|
+
const byComponent = {
|
|
145
|
+
VDialog: set.dialog,
|
|
146
|
+
VMenu: set.menu,
|
|
147
|
+
// Shadows the `VMenu` default above rather than inheriting it.
|
|
148
|
+
VSelect: set.menu,
|
|
149
|
+
VTooltip: set.tooltip,
|
|
150
|
+
VSnackbar: set.snackbar,
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return Object.fromEntries(
|
|
154
|
+
Object.entries(byComponent)
|
|
155
|
+
.filter(([, transition]) => transition !== undefined)
|
|
156
|
+
.map(([name, transition]) => [name, { transition }]),
|
|
157
|
+
)
|
|
158
|
+
}
|
|
159
|
+
|
|
76
160
|
/** Applies the same `density` to lists and both table components. */
|
|
77
161
|
export const tables = (density: 'default' | 'comfortable' | 'compact'): VuetiwatchDefaults => ({
|
|
78
162
|
VList: { density },
|