@shortfuse/materialdesignweb 0.5.0 → 0.7.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/README.md +155 -77
- package/bin/generate-css.js +12 -0
- package/components/Badge.css +30 -0
- package/components/Badge.js +15 -0
- package/components/Body.css +14 -0
- package/components/Body.js +7 -0
- package/components/BottomAppBar.css +23 -0
- package/components/BottomAppBar.js +25 -0
- package/components/Box.css +31 -0
- package/components/Box.js +24 -0
- package/components/Button.css +146 -0
- package/components/Button.js +95 -0
- package/components/Button.md +61 -0
- package/components/Card.css +109 -0
- package/components/Card.js +82 -0
- package/components/Checkbox.css +77 -0
- package/components/Checkbox.js +59 -0
- package/components/CheckboxIcon.css +89 -0
- package/components/CheckboxIcon.js +41 -0
- package/components/Chip.css +35 -0
- package/components/Chip.js +22 -0
- package/components/Dialog.css +235 -0
- package/components/Dialog.js +327 -0
- package/components/DialogActions.js +13 -0
- package/components/Divider.css +41 -0
- package/components/Divider.js +13 -0
- package/components/ExtendedFab.css +24 -0
- package/components/ExtendedFab.js +11 -0
- package/components/Fab.css +23 -0
- package/components/Fab.js +26 -0
- package/components/FilterChip.css +80 -0
- package/components/FilterChip.js +51 -0
- package/components/Headline.css +14 -0
- package/components/Headline.js +33 -0
- package/components/Icon.css +76 -0
- package/components/Icon.js +174 -0
- package/components/IconButton.css +151 -0
- package/components/IconButton.js +65 -0
- package/components/Input.js +16 -0
- package/components/Label.css +14 -0
- package/components/Label.js +7 -0
- package/components/Layout.css +19 -0
- package/components/Layout.js +12 -0
- package/components/List.css +12 -0
- package/components/List.js +17 -0
- package/components/ListItem.css +224 -0
- package/components/ListItem.js +112 -0
- package/components/ListOption.css +34 -0
- package/components/ListOption.js +122 -0
- package/components/ListSelect.css +9 -0
- package/components/ListSelect.js +206 -0
- package/components/Menu.css +171 -0
- package/components/Menu.js +470 -0
- package/components/MenuItem.css +53 -0
- package/components/MenuItem.js +215 -0
- package/components/Nav.css +17 -0
- package/components/Nav.js +23 -0
- package/components/NavBar.css +34 -0
- package/components/NavBar.js +88 -0
- package/components/NavBarItem.css +41 -0
- package/components/NavBarItem.js +7 -0
- package/components/NavDrawer.css +31 -0
- package/components/NavDrawer.js +13 -0
- package/components/NavDrawerItem.css +42 -0
- package/components/NavDrawerItem.js +12 -0
- package/components/NavItem.css +181 -0
- package/components/NavItem.js +83 -0
- package/components/NavRail.css +47 -0
- package/components/NavRail.js +17 -0
- package/components/NavRailItem.css +25 -0
- package/components/NavRailItem.js +7 -0
- package/components/Option.js +91 -0
- package/components/Outline.css +138 -0
- package/components/Pane.css +261 -0
- package/components/Pane.js +21 -0
- package/components/Progress.css +74 -0
- package/components/Progress.js +67 -0
- package/components/ProgressCircle.css +226 -0
- package/components/ProgressLine.css +155 -0
- package/components/Radio.css +83 -0
- package/components/Radio.js +42 -0
- package/components/RadioIcon.css +73 -0
- package/components/RadioIcon.js +37 -0
- package/components/Ripple.css +74 -0
- package/components/Ripple.js +114 -0
- package/components/SegmentedButton.css +94 -0
- package/components/SegmentedButton.js +49 -0
- package/components/SegmentedButtonGroup.css +12 -0
- package/components/SegmentedButtonGroup.js +44 -0
- package/components/Select.css +52 -0
- package/components/Select.js +71 -0
- package/components/Shape.css +132 -0
- package/components/Shape.js +25 -0
- package/components/Slider.css +306 -0
- package/components/Slider.js +206 -0
- package/components/Snackbar.css +80 -0
- package/components/Snackbar.js +75 -0
- package/components/Surface.css +10 -0
- package/components/Surface.js +23 -0
- package/components/Switch.css +63 -0
- package/components/Switch.js +127 -0
- package/components/SwitchIcon.css +177 -0
- package/components/SwitchIcon.js +89 -0
- package/components/SwitchIconAnimations.css +89 -0
- package/components/Tab.css +85 -0
- package/components/Tab.js +103 -0
- package/components/TabContent.js +151 -0
- package/components/TabList.css +129 -0
- package/components/TabList.js +309 -0
- package/components/TabPanel.js +37 -0
- package/components/TextArea.css +93 -0
- package/components/TextArea.js +229 -0
- package/components/Title.css +14 -0
- package/components/Title.js +15 -0
- package/components/Tooltip.css +40 -0
- package/components/Tooltip.js +22 -0
- package/components/TopAppBar.css +209 -0
- package/components/TopAppBar.js +201 -0
- package/core/Composition.js +988 -0
- package/core/CustomElement.js +844 -0
- package/core/ICustomElement.d.ts +288 -0
- package/core/ICustomElement.js +1 -0
- package/core/css.js +51 -0
- package/core/customTypes.js +125 -0
- package/core/dom.js +56 -154
- package/core/identify.js +40 -0
- package/core/observe.js +410 -0
- package/core/template.js +121 -0
- package/core/typings.d.ts +135 -0
- package/core/typings.js +1 -0
- package/mixins/AriaReflectorMixin.js +42 -0
- package/mixins/AriaToolbarMixin.js +13 -0
- package/mixins/ControlMixin.css +57 -0
- package/mixins/ControlMixin.js +212 -0
- package/mixins/DensityMixin.css +40 -0
- package/mixins/DensityMixin.js +11 -0
- package/mixins/FlexableMixin.css +79 -0
- package/mixins/FlexableMixin.js +32 -0
- package/mixins/FormAssociatedMixin.js +170 -0
- package/mixins/InputMixin.js +335 -0
- package/mixins/KeyboardNavMixin.js +244 -0
- package/mixins/RTLObserverMixin.js +35 -0
- package/mixins/ResizeObserverMixin.js +38 -0
- package/mixins/RippleMixin.css +12 -0
- package/mixins/RippleMixin.js +115 -0
- package/mixins/ScrollListenerMixin.js +100 -0
- package/mixins/ShapeMixin.css +135 -0
- package/mixins/ShapeMixin.js +31 -0
- package/mixins/StateMixin.css +82 -0
- package/mixins/StateMixin.js +114 -0
- package/mixins/SurfaceMixin.css +150 -0
- package/mixins/SurfaceMixin.js +32 -0
- package/mixins/TextFieldMixin.css +657 -0
- package/mixins/TextFieldMixin.js +121 -0
- package/mixins/ThemableMixin.css +204 -0
- package/mixins/ThemableMixin.js +16 -0
- package/mixins/TooltipTriggerMixin.css +27 -0
- package/mixins/TooltipTriggerMixin.js +366 -0
- package/mixins/TouchTargetMixin.css +26 -0
- package/mixins/TouchTargetMixin.js +9 -0
- package/package.json +54 -49
- package/theming/index.js +594 -0
- package/theming/loader.js +24 -0
- package/utils/cli.js +11 -0
- package/utils/color_keywords.js +151 -0
- package/utils/hct/Cam16.js +298 -0
- package/utils/hct/CorePalette.js +84 -0
- package/utils/hct/Hct.js +172 -0
- package/utils/hct/Scheme.js +587 -0
- package/utils/hct/TonalPalette.js +68 -0
- package/utils/hct/ViewingConditions.js +136 -0
- package/utils/hct/blend.js +93 -0
- package/utils/hct/colorUtils.js +302 -0
- package/utils/hct/hctSolver.js +559 -0
- package/utils/hct/helper.js +182 -0
- package/utils/hct/mathUtils.js +153 -0
- package/utils/jsonMergePatch.js +100 -0
- package/utils/jsx-runtime.js +101 -0
- package/utils/popup.js +117 -0
- package/utils/svg.js +129 -0
- package/.browserslistrc +0 -4
- package/.eslintrc.json +0 -204
- package/.stylelintrc.json +0 -645
- package/.vscode/launch.json +0 -31
- package/.vscode/settings.json +0 -3
- package/.vscode/tasks.json +0 -32
- package/CHANGELOG.md +0 -36
- package/CODE_OF_CONDUCT.md +0 -46
- package/adapters/datatable/column.js +0 -176
- package/adapters/datatable/index.js +0 -960
- package/adapters/dom/index.js +0 -586
- package/adapters/list/index.js +0 -69
- package/adapters/search/index.js +0 -495
- package/components/appbar/_spec.scss +0 -165
- package/components/appbar/_theme.scss +0 -0
- package/components/appbar/index.scss +0 -2
- package/components/banner/_spec.scss +0 -83
- package/components/banner/_theme.scss +0 -0
- package/components/banner/index.scss +0 -2
- package/components/bottomnav/README.md +0 -85
- package/components/bottomnav/_spec.scss +0 -149
- package/components/bottomnav/_theme.scss +0 -0
- package/components/bottomnav/index.js +0 -117
- package/components/bottomnav/index.scss +0 -2
- package/components/bottomnav/item.js +0 -88
- package/components/button/README.md +0 -61
- package/components/button/_spec.scss +0 -162
- package/components/button/_theme.scss +0 -42
- package/components/button/index.eta +0 -32
- package/components/button/index.js +0 -43
- package/components/button/index.pug +0 -18
- package/components/button/index.scss +0 -2
- package/components/card/_spec.scss +0 -241
- package/components/card/_theme.scss +0 -0
- package/components/card/index.scss +0 -2
- package/components/chip/_spec.scss +0 -111
- package/components/chip/_theme.scss +0 -105
- package/components/chip/index.js +0 -23
- package/components/chip/index.scss +0 -2
- package/components/chip/item.js +0 -20
- package/components/datatable/_spec.scss +0 -225
- package/components/datatable/_theme.scss +0 -128
- package/components/datatable/cell.js +0 -44
- package/components/datatable/columnheader.js +0 -46
- package/components/datatable/index.js +0 -374
- package/components/datatable/index.scss +0 -2
- package/components/datatable/row.js +0 -48
- package/components/datatable/rowheader.js +0 -18
- package/components/dialog/_spec.scss +0 -203
- package/components/dialog/_theme.scss +0 -7
- package/components/dialog/index.js +0 -601
- package/components/dialog/index.scss +0 -2
- package/components/divider/_spec.scss +0 -11
- package/components/divider/_theme.scss +0 -0
- package/components/divider/index.scss +0 -2
- package/components/elevation/_spec.scss +0 -9
- package/components/elevation/_theme.scss +0 -0
- package/components/elevation/index.scss +0 -2
- package/components/fab/_spec.scss +0 -210
- package/components/fab/_theme.scss +0 -0
- package/components/fab/index.js +0 -99
- package/components/fab/index.scss +0 -2
- package/components/grid/_spec.scss +0 -169
- package/components/grid/_theme.scss +0 -0
- package/components/grid/index.scss +0 -2
- package/components/layout/_mixins.scss +0 -11
- package/components/layout/_spec.scss +0 -916
- package/components/layout/_theme.scss +0 -19
- package/components/layout/index.js +0 -454
- package/components/layout/index.scss +0 -2
- package/components/list/_spec.scss +0 -363
- package/components/list/_theme.scss +0 -102
- package/components/list/content.js +0 -106
- package/components/list/index.js +0 -256
- package/components/list/index.scss +0 -2
- package/components/list/item.js +0 -167
- package/components/list/secondary.js +0 -45
- package/components/menu/_spec.scss +0 -329
- package/components/menu/_theme.scss +0 -0
- package/components/menu/index.js +0 -705
- package/components/menu/index.scss +0 -2
- package/components/menu/item.js +0 -231
- package/components/progress/_spec.scss +0 -156
- package/components/progress/_theme.scss +0 -0
- package/components/progress/index.js +0 -36
- package/components/progress/index.scss +0 -2
- package/components/selection/_spec.scss +0 -376
- package/components/selection/_theme.scss +0 -134
- package/components/selection/index.eta +0 -60
- package/components/selection/index.js +0 -70
- package/components/selection/index.pug +0 -30
- package/components/selection/index.scss +0 -2
- package/components/selection/input.js +0 -54
- package/components/selection/radiogroup.js +0 -40
- package/components/slider/_spec.scss +0 -59
- package/components/slider/_theme.scss +0 -0
- package/components/slider/index.scss +0 -2
- package/components/snackbar/_spec.scss +0 -150
- package/components/snackbar/_theme.scss +0 -0
- package/components/snackbar/index.js +0 -338
- package/components/snackbar/index.scss +0 -2
- package/components/tab/_spec.scss +0 -220
- package/components/tab/_theme.scss +0 -0
- package/components/tab/content.js +0 -210
- package/components/tab/index.js +0 -257
- package/components/tab/index.scss +0 -2
- package/components/tab/item.js +0 -88
- package/components/tab/list.js +0 -196
- package/components/tab/panel.js +0 -54
- package/components/textfield/README.md +0 -179
- package/components/textfield/_spec.scss +0 -763
- package/components/textfield/_theme.scss +0 -264
- package/components/textfield/index.eta +0 -74
- package/components/textfield/index.js +0 -160
- package/components/textfield/index.pug +0 -30
- package/components/textfield/index.scss +0 -2
- package/components/tooltip/_spec.scss +0 -185
- package/components/tooltip/_theme.scss +0 -0
- package/components/tooltip/index.scss +0 -2
- package/components/type/_spec.scss +0 -227
- package/components/type/_theme.scss +0 -0
- package/components/type/index.scss +0 -2
- package/core/_breakpoint.scss +0 -189
- package/core/_elevation.scss +0 -78
- package/core/_length.scss +0 -8
- package/core/_motion.scss +0 -31
- package/core/_platform.scss +0 -12
- package/core/_type.scss +0 -128
- package/core/aria/attributes.js +0 -141
- package/core/aria/button.js +0 -49
- package/core/aria/keyboard.js +0 -92
- package/core/aria/rovingtabindex.js +0 -175
- package/core/aria/tab.js +0 -59
- package/core/document/index.js +0 -39
- package/core/overlay/_spec.scss +0 -28
- package/core/overlay/_theme.scss +0 -147
- package/core/overlay/index.js +0 -95
- package/core/overlay/index.scss +0 -2
- package/core/ripple/_spec.scss +0 -196
- package/core/ripple/_theme.scss +0 -20
- package/core/ripple/index.js +0 -286
- package/core/ripple/index.scss +0 -2
- package/core/theme/_aliases.scss +0 -15
- package/core/theme/_config.scss +0 -8
- package/core/theme/_functions.scss +0 -22
- package/core/theme/_palettes.scss +0 -405
- package/core/theme/_spec.scss +0 -0
- package/core/theme/_theme.scss +0 -268
- package/core/theme/index.js +0 -50
- package/core/theme/index.scss +0 -4
- package/core/throttler.js +0 -42
- package/core/transition/index.js +0 -465
- package/docs/_flex.scss +0 -28
- package/docs/_menuoptions.js +0 -183
- package/docs/_partials/_androidnavbar.eta +0 -5
- package/docs/_partials/_androidstatusbar.eta +0 -13
- package/docs/_partials/_appbar.eta +0 -27
- package/docs/_partials/_buttontest.eta +0 -31
- package/docs/_partials/_header.eta +0 -146
- package/docs/_partials/_navlistitem.eta +0 -16
- package/docs/_partials/_target.eta +0 -1
- package/docs/_sample-utils.js +0 -88
- package/docs/_storage.js +0 -33
- package/docs/docs.scss +0 -331
- package/docs/framework.scss +0 -26
- package/docs/index.eta +0 -12
- package/docs/index.js +0 -7
- package/docs/pages/appbar.eta +0 -108
- package/docs/pages/appbar.js +0 -0
- package/docs/pages/bottomnav.eta +0 -188
- package/docs/pages/bottomnav.js +0 -118
- package/docs/pages/button.eta +0 -124
- package/docs/pages/button.js +0 -224
- package/docs/pages/card.eta +0 -90
- package/docs/pages/card.js +0 -175
- package/docs/pages/chip.eta +0 -122
- package/docs/pages/chip.js +0 -80
- package/docs/pages/color.eta +0 -143
- package/docs/pages/color.js +0 -261
- package/docs/pages/datatable.eta +0 -323
- package/docs/pages/datatable.js +0 -160
- package/docs/pages/dialog.eta +0 -184
- package/docs/pages/dialog.js +0 -174
- package/docs/pages/dom.eta +0 -26
- package/docs/pages/dom.js +0 -140
- package/docs/pages/elevation.eta +0 -35
- package/docs/pages/elevation.js +0 -0
- package/docs/pages/fab.eta +0 -99
- package/docs/pages/fab.js +0 -43
- package/docs/pages/grid.eta +0 -135
- package/docs/pages/grid.js +0 -128
- package/docs/pages/layout.eta +0 -8
- package/docs/pages/layout.js +0 -0
- package/docs/pages/list.eta +0 -465
- package/docs/pages/list.js +0 -8
- package/docs/pages/menu.eta +0 -274
- package/docs/pages/menu.js +0 -213
- package/docs/pages/overlay.eta +0 -69
- package/docs/pages/overlay.js +0 -3
- package/docs/pages/progress.eta +0 -23
- package/docs/pages/progress.js +0 -12
- package/docs/pages/ripple.eta +0 -27
- package/docs/pages/ripple.js +0 -3
- package/docs/pages/search.eta +0 -242
- package/docs/pages/search.js +0 -226
- package/docs/pages/selection.eta +0 -107
- package/docs/pages/selection.js +0 -12
- package/docs/pages/slider.eta +0 -23
- package/docs/pages/slider.js +0 -0
- package/docs/pages/snackbar.eta +0 -83
- package/docs/pages/snackbar.js +0 -157
- package/docs/pages/tab.eta +0 -407
- package/docs/pages/tab.js +0 -152
- package/docs/pages/textfield.eta +0 -487
- package/docs/pages/textfield.js +0 -257
- package/docs/pages/tooltip.eta +0 -92
- package/docs/pages/tooltip.js +0 -0
- package/docs/pages/transition.eta +0 -117
- package/docs/pages/transition.js +0 -52
- package/docs/pages/type.eta +0 -31
- package/docs/pages/type.js +0 -0
- package/docs/postrender.js +0 -41
- package/docs/prerender.js +0 -16
- package/docs/pwa/_dialogs.eta +0 -143
- package/docs/pwa/_menus.eta +0 -16
- package/docs/pwa/pwa-prerender.js +0 -3
- package/docs/pwa/pwa.eta +0 -478
- package/docs/pwa/pwa.js +0 -298
- package/docs/pwa/pwa.scss +0 -31
- package/docs/themes/theme-colored.scss +0 -15
- package/docs/themes/theme-default.scss +0 -3
- package/index.scss +0 -27
- package/jsconfig.json +0 -16
- package/scripts/deploy-docs.sh +0 -9
- package/templates/index.eta +0 -2
- package/templates/index.pug +0 -3
- package/tsconfig.json +0 -16
- package/webpack.config.js +0 -304
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import CorePalette from './CorePalette.js';
|
|
2
|
+
import Scheme from './Scheme.js';
|
|
3
|
+
import { harmonize } from './blend.js';
|
|
4
|
+
import * as colorUtils from './colorUtils.js';
|
|
5
|
+
|
|
6
|
+
/** @typedef {import('./TonalPalette.js').default} TonalPalette */
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {string} value
|
|
10
|
+
* @return {number}
|
|
11
|
+
*/
|
|
12
|
+
function parseIntHex(value) {
|
|
13
|
+
// tslint:disable-next-line:ban
|
|
14
|
+
return Number.parseInt(value, 16);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {string} hex String representing color as hex code. Accepts strings with or
|
|
19
|
+
* without leading #, and string representing the color using 3, 6, or 8
|
|
20
|
+
* hex characters.
|
|
21
|
+
* @return {number} ARGB representation of color.
|
|
22
|
+
*/
|
|
23
|
+
function argbFromHex(hex) {
|
|
24
|
+
hex = hex.replace('#', '');
|
|
25
|
+
const isThree = hex.length === 3;
|
|
26
|
+
const isSix = hex.length === 6;
|
|
27
|
+
const isEight = hex.length === 8;
|
|
28
|
+
if (!isThree && !isSix && !isEight) {
|
|
29
|
+
throw new Error(`unexpected hex ${hex}`);
|
|
30
|
+
}
|
|
31
|
+
let r = 0;
|
|
32
|
+
let g = 0;
|
|
33
|
+
let b = 0;
|
|
34
|
+
if (isThree) {
|
|
35
|
+
r = parseIntHex(hex.slice(0, 1).repeat(2));
|
|
36
|
+
g = parseIntHex(hex.slice(1, 2).repeat(2));
|
|
37
|
+
b = parseIntHex(hex.slice(2, 3).repeat(2));
|
|
38
|
+
} else if (isSix) {
|
|
39
|
+
r = parseIntHex(hex.slice(0, 2));
|
|
40
|
+
g = parseIntHex(hex.slice(2, 4));
|
|
41
|
+
b = parseIntHex(hex.slice(4, 6));
|
|
42
|
+
} else if (isEight) {
|
|
43
|
+
r = parseIntHex(hex.slice(2, 4));
|
|
44
|
+
g = parseIntHex(hex.slice(4, 6));
|
|
45
|
+
b = parseIntHex(hex.slice(6, 8));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
((255 << 24) | ((r & 0x0_FF) << 16) | ((g & 0x0_FF) << 8) | (b & 0x0_FF))
|
|
50
|
+
>>> 0);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @param {number} argb ARGB representation of a color.
|
|
55
|
+
* @return {string} Hex string representing color, ex. #ff0000 for red.
|
|
56
|
+
*/
|
|
57
|
+
function hexFromArgb(argb) {
|
|
58
|
+
const r = colorUtils.redFromArgb(argb);
|
|
59
|
+
const g = colorUtils.greenFromArgb(argb);
|
|
60
|
+
const b = colorUtils.blueFromArgb(argb);
|
|
61
|
+
const outParts = [r.toString(16), g.toString(16), b.toString(16)];
|
|
62
|
+
|
|
63
|
+
// Pad single-digit output values
|
|
64
|
+
for (const [i, part] of outParts.entries()) {
|
|
65
|
+
if (part.length === 1) {
|
|
66
|
+
outParts[i] = `0${part}`;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return `#${outParts.join('')}`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @param {number} argb
|
|
75
|
+
* @return {string}
|
|
76
|
+
*/
|
|
77
|
+
function cssVarFromArgb(argb) {
|
|
78
|
+
return [
|
|
79
|
+
colorUtils.redFromArgb(argb),
|
|
80
|
+
colorUtils.greenFromArgb(argb),
|
|
81
|
+
colorUtils.blueFromArgb(argb),
|
|
82
|
+
].join(',');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @param {Scheme} scheme
|
|
87
|
+
* @return {string}
|
|
88
|
+
*/
|
|
89
|
+
function cssVariablesFromScheme(scheme) {
|
|
90
|
+
return /* css */`
|
|
91
|
+
:root {
|
|
92
|
+
--mdw-color__primary: ${cssVarFromArgb(scheme.primary)};
|
|
93
|
+
--mdw-color__on-primary: ${cssVarFromArgb(scheme.onPrimary)};
|
|
94
|
+
--mdw-color__primary-container: ${cssVarFromArgb(scheme.primaryContainer)};
|
|
95
|
+
--mdw-color__on-primary-container: ${cssVarFromArgb(scheme.onPrimaryContainer)};
|
|
96
|
+
--mdw-color__secondary: ${cssVarFromArgb(scheme.secondary)};
|
|
97
|
+
--mdw-color__on-secondary: ${cssVarFromArgb(scheme.onSecondary)};
|
|
98
|
+
--mdw-color__secondary-container: ${cssVarFromArgb(scheme.secondaryContainer)};
|
|
99
|
+
--mdw-color__on-secondary-container: ${cssVarFromArgb(scheme.onSecondaryContainer)};
|
|
100
|
+
--mdw-color__tertiary: ${cssVarFromArgb(scheme.tertiary)};
|
|
101
|
+
--mdw-color__on-tertiary: ${cssVarFromArgb(scheme.onTertiary)};
|
|
102
|
+
--mdw-color__tertiary-container: ${cssVarFromArgb(scheme.tertiaryContainer)};
|
|
103
|
+
--mdw-color__on-tertiary-container: ${cssVarFromArgb(scheme.onTertiaryContainer)};
|
|
104
|
+
--mdw-color__error: ${cssVarFromArgb(scheme.error)};
|
|
105
|
+
--mdw-color__on-error: ${cssVarFromArgb(scheme.onError)};
|
|
106
|
+
--mdw-color__error-container: ${cssVarFromArgb(scheme.errorContainer)};
|
|
107
|
+
--mdw-color__on-error-container: ${cssVarFromArgb(scheme.onErrorContainer)};
|
|
108
|
+
--mdw-color__background: ${cssVarFromArgb(scheme.background)};
|
|
109
|
+
--mdw-color__on-background: ${cssVarFromArgb(scheme.onBackground)};
|
|
110
|
+
--mdw-color__surface: ${cssVarFromArgb(scheme.surface)};
|
|
111
|
+
--mdw-color__on-surface: ${cssVarFromArgb(scheme.onSurface)};
|
|
112
|
+
--mdw-color__surface-variant: ${cssVarFromArgb(scheme.surfaceVariant)};
|
|
113
|
+
--mdw-color__on-surface-variant: ${cssVarFromArgb(scheme.onSurfaceVariant)};
|
|
114
|
+
--mdw-color__outline: ${cssVarFromArgb(scheme.outline)};
|
|
115
|
+
--mdw-color__outline-variant: ${cssVarFromArgb(scheme.outlineVariant)};
|
|
116
|
+
--mdw-color__shadow: ${cssVarFromArgb(scheme.shadow)};
|
|
117
|
+
--mdw-color__scrim: ${cssVarFromArgb(scheme.scrim)};
|
|
118
|
+
--mdw-color__inverse-surface: ${cssVarFromArgb(scheme.inverseSurface)};
|
|
119
|
+
--mdw-color__inverse-on-surface: ${cssVarFromArgb(scheme.inverseOnSurface)};
|
|
120
|
+
--mdw-color__inverse-primary: ${cssVarFromArgb(scheme.inversePrimary)};
|
|
121
|
+
}
|
|
122
|
+
`;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @param {string} name
|
|
127
|
+
* @param {TonalPalette} tonalPalette
|
|
128
|
+
* @param {boolean} [isDark]
|
|
129
|
+
*/
|
|
130
|
+
function cssVariablesFromCustom(name, tonalPalette, isDark) {
|
|
131
|
+
return /* css */`
|
|
132
|
+
:root {
|
|
133
|
+
--mdw-color__${name}: ${cssVarFromArgb(tonalPalette.tone(isDark ? 80 : 40))};
|
|
134
|
+
--mdw-color__on-${name}: ${cssVarFromArgb(tonalPalette.tone(isDark ? 20 : 100))};
|
|
135
|
+
--mdw-color__${name}-container: ${cssVarFromArgb(tonalPalette.tone(isDark ? 30 : 90))};
|
|
136
|
+
--mdw-color__on-${name}-container: ${cssVarFromArgb(tonalPalette.tone(isDark ? 90 : 10))};
|
|
137
|
+
}
|
|
138
|
+
.mdw-custom[color="${name}"] {
|
|
139
|
+
--mdw-bg: var(--mdw-color__${name});
|
|
140
|
+
--mdw-ink: var(--mdw-color__on-${name});
|
|
141
|
+
}
|
|
142
|
+
.mdw-custom[color="${name}-container"] {
|
|
143
|
+
--mdw-bg: var(--mdw-color__${name}-container);
|
|
144
|
+
--mdw-ink: var(--mdw-color__on-${name}-container);
|
|
145
|
+
}
|
|
146
|
+
.mdw-custom[ink="${name}"] {
|
|
147
|
+
--mdw-ink: var(--mdw-color__${name});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
`;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @param {string} mainColor as hex
|
|
156
|
+
* @param {Iterable<[string,string]>} [customColors]
|
|
157
|
+
* @return {Record<string, string>}
|
|
158
|
+
*/
|
|
159
|
+
export function getScheme(mainColor, customColors = []) {
|
|
160
|
+
const argbColor = argbFromHex(mainColor);
|
|
161
|
+
const lightRules = [cssVariablesFromScheme(Scheme.light(argbColor))];
|
|
162
|
+
const darkRules = [cssVariablesFromScheme(Scheme.dark(argbColor))];
|
|
163
|
+
const lightContentRules = [cssVariablesFromScheme(Scheme.lightContent(argbColor))];
|
|
164
|
+
const darkContentRules = [cssVariablesFromScheme(Scheme.darkContent(argbColor))];
|
|
165
|
+
for (const [name, color] of customColors) {
|
|
166
|
+
const argbCustom = argbFromHex(color);
|
|
167
|
+
const blended = harmonize(argbCustom, argbColor);
|
|
168
|
+
const { a1: tp } = CorePalette.of(blended);
|
|
169
|
+
const { a1: ctp } = CorePalette.contentOf(blended);
|
|
170
|
+
|
|
171
|
+
lightRules.push(cssVariablesFromCustom(name, tp));
|
|
172
|
+
darkRules.push(cssVariablesFromCustom(name, tp, true));
|
|
173
|
+
lightContentRules.push(cssVariablesFromCustom(name, ctp));
|
|
174
|
+
darkContentRules.push(cssVariablesFromCustom(name, ctp, true));
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
light: lightRules.join('\n'),
|
|
178
|
+
dark: darkRules.join('\n'),
|
|
179
|
+
lightContent: lightContentRules.join('\n'),
|
|
180
|
+
darkContent: darkContentRules.join('\n'),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2021 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// This file is automatically generated. Do not modify it.
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Utility methods for mathematical operations.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The signum function.
|
|
26
|
+
* @param {number} num
|
|
27
|
+
* @return {1|-1|0} 1 if num > 0, -1 if num < 0, and 0 if num = 0
|
|
28
|
+
*/
|
|
29
|
+
export function signum(num) {
|
|
30
|
+
if (num < 0) {
|
|
31
|
+
return -1;
|
|
32
|
+
}
|
|
33
|
+
if (num === 0) {
|
|
34
|
+
return 0;
|
|
35
|
+
}
|
|
36
|
+
return 1;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The linear interpolation function.
|
|
41
|
+
* @param {number} start
|
|
42
|
+
* @param {number} stop
|
|
43
|
+
* @param {number} amount
|
|
44
|
+
* @return {number} start if amount = 0 and stop if amount = 1
|
|
45
|
+
*/
|
|
46
|
+
export function lerp(start, stop, amount) {
|
|
47
|
+
return (1 - amount) * start + amount * stop;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Clamps an integer between two integers.
|
|
52
|
+
* @param {number} min
|
|
53
|
+
* @param {number} max
|
|
54
|
+
* @param {number} input
|
|
55
|
+
* @return {number} input when min <= input <= max, and either min or max
|
|
56
|
+
* otherwise.
|
|
57
|
+
*/
|
|
58
|
+
export function clampInt(min, max, input) {
|
|
59
|
+
if (input < min) {
|
|
60
|
+
return min;
|
|
61
|
+
} if (input > max) {
|
|
62
|
+
return max;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return input;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Clamps an integer between two floating-point numbers.
|
|
70
|
+
* @param {number} min
|
|
71
|
+
* @param {number} max
|
|
72
|
+
* @param {number} input
|
|
73
|
+
* @return {number} input when min <= input <= max, and either min or max
|
|
74
|
+
* otherwise.
|
|
75
|
+
*/
|
|
76
|
+
export function clampDouble(min, max, input) {
|
|
77
|
+
if (input < min) {
|
|
78
|
+
return min;
|
|
79
|
+
} if (input > max) {
|
|
80
|
+
return max;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return input;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Sanitizes a degree measure as an integer.
|
|
88
|
+
* @param {number} degrees
|
|
89
|
+
* @return {number} a degree measure between 0 (inclusive) and 360
|
|
90
|
+
* (exclusive).
|
|
91
|
+
*/
|
|
92
|
+
export function sanitizeDegreesInt(degrees) {
|
|
93
|
+
degrees %= 360;
|
|
94
|
+
if (degrees < 0) {
|
|
95
|
+
degrees += 360;
|
|
96
|
+
}
|
|
97
|
+
return degrees;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Sanitizes a degree measure as a floating-point number.
|
|
102
|
+
* @param {number} degrees
|
|
103
|
+
* @return {number} a degree measure between 0.0 (inclusive) and 360.0
|
|
104
|
+
* (exclusive).
|
|
105
|
+
*/
|
|
106
|
+
export function sanitizeDegreesDouble(degrees) {
|
|
107
|
+
degrees %= 360;
|
|
108
|
+
if (degrees < 0) {
|
|
109
|
+
degrees += 360;
|
|
110
|
+
}
|
|
111
|
+
return degrees;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Sign of direction change needed to travel from one angle to
|
|
116
|
+
* another.
|
|
117
|
+
*
|
|
118
|
+
* For angles that are 180 degrees apart from each other, both
|
|
119
|
+
* directions have the same travel distance, so either direction is
|
|
120
|
+
* shortest. The value 1.0 is returned in this case.
|
|
121
|
+
* @param {number} from The angle travel starts from, in degrees.
|
|
122
|
+
* @param {number} to The angle travel ends at, in degrees.
|
|
123
|
+
* @return {number} -1 if decreasing from leads to the shortest travel
|
|
124
|
+
* distance, 1 if increasing from leads to the shortest travel
|
|
125
|
+
* distance.
|
|
126
|
+
*/
|
|
127
|
+
export function rotationDirection(from, to) {
|
|
128
|
+
const increasingDifference = sanitizeDegreesDouble(to - from);
|
|
129
|
+
return increasingDifference <= 180 ? 1 : -1;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Distance of two points on a circle, represented using degrees.
|
|
134
|
+
* @param {number} a
|
|
135
|
+
* @param {number} b
|
|
136
|
+
* @return {number}
|
|
137
|
+
*/
|
|
138
|
+
export function differenceDegrees(a, b) {
|
|
139
|
+
return 180 - Math.abs(Math.abs(a - b) - 180);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Multiplies a 1x3 row vector with a 3x3 matrix.
|
|
144
|
+
* @param {number[]} row
|
|
145
|
+
* @param {number[][]} matrix
|
|
146
|
+
* @return {number[]}
|
|
147
|
+
*/
|
|
148
|
+
export function matrixMultiply(row, matrix) {
|
|
149
|
+
const a = row[0] * matrix[0][0] + row[1] * matrix[0][1] + row[2] * matrix[0][2];
|
|
150
|
+
const b = row[0] * matrix[1][0] + row[1] * matrix[1][1] + row[2] * matrix[1][2];
|
|
151
|
+
const c = row[0] * matrix[2][0] + row[1] * matrix[2][1] + row[2] * matrix[2][2];
|
|
152
|
+
return [a, b, c];
|
|
153
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/** @link https://www.rfc-editor.org/rfc/rfc7396 */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @template T1
|
|
5
|
+
* @template T2
|
|
6
|
+
* @param {T1} target
|
|
7
|
+
* @param {T2} patch
|
|
8
|
+
* @return {T1|T2|(T1 & T2)}
|
|
9
|
+
*/
|
|
10
|
+
export function applyMergePatch(target, patch) {
|
|
11
|
+
if (target === patch) return target;
|
|
12
|
+
if (patch == null || typeof patch !== 'object') return patch;
|
|
13
|
+
if (target != null && typeof target !== 'object') {
|
|
14
|
+
target = {};
|
|
15
|
+
}
|
|
16
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
17
|
+
if (value == null) {
|
|
18
|
+
if (key in target) {
|
|
19
|
+
delete target[key];
|
|
20
|
+
}
|
|
21
|
+
} else {
|
|
22
|
+
target[key] = applyMergePatch(target[key], value);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return target;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Creates a JSON Merge patch based
|
|
30
|
+
* Allows different strategies for arrays
|
|
31
|
+
* - `clone`: Per spec, clones all entries with no inspection.
|
|
32
|
+
* - `object`: Convert to flattened, array-like objects. Requires
|
|
33
|
+
* consumer of patch to be aware of the schema beforehand.
|
|
34
|
+
* @param {object|number|string|boolean} previous
|
|
35
|
+
* @param {object|number|string|boolean} current
|
|
36
|
+
* @param {'clone'|'object'} [arrayStrategy='clone']
|
|
37
|
+
* @return {any} Patch
|
|
38
|
+
*/
|
|
39
|
+
export function buildMergePatch(previous, current, arrayStrategy = 'clone') {
|
|
40
|
+
if (previous === current) return null;
|
|
41
|
+
if (current == null || typeof current !== 'object') return current;
|
|
42
|
+
if (previous == null || typeof previous !== 'object') {
|
|
43
|
+
return structuredClone(current);
|
|
44
|
+
}
|
|
45
|
+
const isArray = Array.isArray(current);
|
|
46
|
+
if (isArray && arrayStrategy === 'clone') {
|
|
47
|
+
return structuredClone(current);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const patch = {};
|
|
51
|
+
const previousKeys = new Set(Object.keys(previous));
|
|
52
|
+
for (const [key, value] of Object.entries(current)) {
|
|
53
|
+
previousKeys.delete(key);
|
|
54
|
+
if (value == null) {
|
|
55
|
+
console.warn('Nullish value found at', key);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const changes = buildMergePatch(previous[key], value, arrayStrategy);
|
|
59
|
+
if (changes === null) {
|
|
60
|
+
console.log('keeping', key);
|
|
61
|
+
} else {
|
|
62
|
+
patch[key] = changes;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
for (const key of previousKeys) {
|
|
66
|
+
patch[key] = null;
|
|
67
|
+
console.log('removing', key);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (isArray && arrayStrategy === 'object' && current.length !== previous.length) {
|
|
71
|
+
patch.length = current.length;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return patch;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Short-circuited JSON Merge Patch evaluation
|
|
79
|
+
* @template T
|
|
80
|
+
* @param {T} target
|
|
81
|
+
* @param {Partial<T>} patch
|
|
82
|
+
* @return {boolean}
|
|
83
|
+
*/
|
|
84
|
+
export function hasMergePatch(target, patch) {
|
|
85
|
+
if (target === patch) return false;
|
|
86
|
+
if (patch == null || typeof patch !== 'object') return true;
|
|
87
|
+
if (target != null && typeof target !== 'object') {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
91
|
+
if (value == null) {
|
|
92
|
+
if (key in target) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
} else if (hasMergePatch(target[key], value)) {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/** eslint-env browser */
|
|
2
|
+
|
|
3
|
+
export const Fragment = '$FRAGMENT';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {string} tagName
|
|
7
|
+
* @param {Record<string, any> & { children: HTMLElement[], style:string|CSSStyleDeclaration }} attrs
|
|
8
|
+
* @return {HTMLElement|DocumentFragment}
|
|
9
|
+
*/
|
|
10
|
+
function createElementStatic(tagName, attrs) {
|
|
11
|
+
const { children } = attrs;
|
|
12
|
+
if (!children) throw new Error('Static elements much have children');
|
|
13
|
+
|
|
14
|
+
if (tagName === Fragment) {
|
|
15
|
+
const fragment = document.createDocumentFragment();
|
|
16
|
+
fragment.append(...children);
|
|
17
|
+
return fragment;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const element = document.createElement(tagName);
|
|
21
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
22
|
+
switch (key) {
|
|
23
|
+
case 'children':
|
|
24
|
+
element.append(...value);
|
|
25
|
+
break;
|
|
26
|
+
case 'class':
|
|
27
|
+
if (typeof value === 'string') {
|
|
28
|
+
element.classList.add(...(value.split(' ')));
|
|
29
|
+
} else {
|
|
30
|
+
element.classList.add(...value);
|
|
31
|
+
}
|
|
32
|
+
break;
|
|
33
|
+
case 'style':
|
|
34
|
+
if (typeof value === 'string') {
|
|
35
|
+
element.setAttribute('style', value);
|
|
36
|
+
} else {
|
|
37
|
+
Object.assign(element.style, value);
|
|
38
|
+
}
|
|
39
|
+
break;
|
|
40
|
+
default:
|
|
41
|
+
if (key in element) {
|
|
42
|
+
element[key] = value;
|
|
43
|
+
} else if (key.startsWith('data-')) {
|
|
44
|
+
element.dataset[key.slice('data-'.length)] = value;
|
|
45
|
+
} else {
|
|
46
|
+
element.setAttribute(key, value ?? '');
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return element;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @param {string} tagName
|
|
55
|
+
* @param {{ children?: DocumentFragment|string }} attrs
|
|
56
|
+
* @return {HTMLElement|DocumentFragment}
|
|
57
|
+
*/
|
|
58
|
+
function createElementDynamic(tagName, attrs = {}) {
|
|
59
|
+
if (tagName === Fragment) {
|
|
60
|
+
const fragment = document.createDocumentFragment();
|
|
61
|
+
const { children } = attrs;
|
|
62
|
+
if (children == null) return fragment;
|
|
63
|
+
fragment.append(children);
|
|
64
|
+
return fragment;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const element = document.createElement(tagName);
|
|
68
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
69
|
+
switch (key) {
|
|
70
|
+
case 'children':
|
|
71
|
+
element.append(value);
|
|
72
|
+
break;
|
|
73
|
+
case 'class':
|
|
74
|
+
if (typeof value === 'string') {
|
|
75
|
+
element.classList.add(...(value.split(' ')));
|
|
76
|
+
} else {
|
|
77
|
+
element.classList.add(...value);
|
|
78
|
+
}
|
|
79
|
+
break;
|
|
80
|
+
case 'style':
|
|
81
|
+
if (typeof value === 'string') {
|
|
82
|
+
element.setAttribute('style', value);
|
|
83
|
+
} else {
|
|
84
|
+
Object.assign(element.style, value);
|
|
85
|
+
}
|
|
86
|
+
break;
|
|
87
|
+
default:
|
|
88
|
+
if (key in element) {
|
|
89
|
+
element[key] = value;
|
|
90
|
+
} else if (key.startsWith('data-')) {
|
|
91
|
+
element.dataset[key.slice('data-'.length)] = value;
|
|
92
|
+
} else {
|
|
93
|
+
element.setAttribute(key, value ?? '');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return element;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export const jsx = createElementDynamic;
|
|
101
|
+
export const jsxs = createElementStatic;
|
package/utils/popup.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} CanAnchorPopUpOptions
|
|
3
|
+
* @prop {Element|DOMRect} [anchor]
|
|
4
|
+
* @prop {number|'left'|'center'|'right'} [clientX]
|
|
5
|
+
* @prop {number|'top'|'center'|'bottom'} [clientY]
|
|
6
|
+
* @prop {number} [pageX]
|
|
7
|
+
* @prop {number} [pageY]
|
|
8
|
+
* @prop {Element|DOMRect} [popup]
|
|
9
|
+
* @prop {number} [width]
|
|
10
|
+
* @prop {number} [height]
|
|
11
|
+
* @prop {number} [offsetX] Offset from anchor
|
|
12
|
+
* @prop {number} [offsetY] Offset from anchor
|
|
13
|
+
* @prop {number} [margin] Margin from page
|
|
14
|
+
* @prop {'left'|'center'|'right'} [directionX='right']
|
|
15
|
+
* @prop {'up'|'center'|'down'} [directionY='down']
|
|
16
|
+
* @prop {boolean} [force=false]
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** @param {CanAnchorPopUpOptions} options */
|
|
20
|
+
export function canAnchorPopup(options) {
|
|
21
|
+
let { pageX, pageY, directionX, directionY } = options;
|
|
22
|
+
if (pageX == null || pageY == null) {
|
|
23
|
+
const { clientX, clientY, anchor } = options;
|
|
24
|
+
const rect = anchor instanceof Element ? anchor.getBoundingClientRect() : anchor;
|
|
25
|
+
if (pageX == null) {
|
|
26
|
+
switch (clientX) {
|
|
27
|
+
case 'left':
|
|
28
|
+
case null:
|
|
29
|
+
case undefined:
|
|
30
|
+
pageX = rect.left;
|
|
31
|
+
directionX ??= 'right';
|
|
32
|
+
break;
|
|
33
|
+
case 'center':
|
|
34
|
+
pageX = rect.left + rect.width / 2;
|
|
35
|
+
directionX ??= 'center';
|
|
36
|
+
break;
|
|
37
|
+
case 'right':
|
|
38
|
+
pageX = rect.right;
|
|
39
|
+
directionX ??= 'left';
|
|
40
|
+
break;
|
|
41
|
+
default:
|
|
42
|
+
pageX = rect.left + clientX;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (pageY == null) {
|
|
46
|
+
switch (clientY) {
|
|
47
|
+
case 'top':
|
|
48
|
+
pageY = rect.top;
|
|
49
|
+
directionY ??= 'up';
|
|
50
|
+
break;
|
|
51
|
+
case 'center':
|
|
52
|
+
pageY = rect.top + rect.height / 2;
|
|
53
|
+
directionY ??= 'center';
|
|
54
|
+
break;
|
|
55
|
+
case 'bottom':
|
|
56
|
+
case null:
|
|
57
|
+
case undefined:
|
|
58
|
+
pageY = rect.bottom;
|
|
59
|
+
directionY ??= 'down';
|
|
60
|
+
break;
|
|
61
|
+
default:
|
|
62
|
+
pageY = rect.top + clientY;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
let { width, height } = options;
|
|
67
|
+
if (width == null || height == null) {
|
|
68
|
+
const { popup } = options;
|
|
69
|
+
if (popup instanceof Element) {
|
|
70
|
+
width = popup.clientWidth;
|
|
71
|
+
height = popup.clientHeight;
|
|
72
|
+
} else {
|
|
73
|
+
width = popup.width;
|
|
74
|
+
height = popup.width;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// eslint-disable-next-line default-case
|
|
79
|
+
switch (directionX) {
|
|
80
|
+
case 'left':
|
|
81
|
+
pageX -= width;
|
|
82
|
+
break;
|
|
83
|
+
case 'center':
|
|
84
|
+
pageX -= width / 2;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// eslint-disable-next-line default-case
|
|
88
|
+
switch (directionY) {
|
|
89
|
+
case 'up':
|
|
90
|
+
pageY -= height;
|
|
91
|
+
break;
|
|
92
|
+
case 'center':
|
|
93
|
+
pageY -= height / 2;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const offsetX = options.offsetX ?? 0;
|
|
97
|
+
const offsetY = options.offsetY ?? 0;
|
|
98
|
+
pageX += offsetX;
|
|
99
|
+
pageY += offsetY;
|
|
100
|
+
const margin = options.margin ?? 0;
|
|
101
|
+
if (!options.force) {
|
|
102
|
+
if (pageX - margin < 0) return null;
|
|
103
|
+
if (pageY - margin < 0) return null;
|
|
104
|
+
if (pageX + width > (document.documentElement.clientWidth - margin)) return null;
|
|
105
|
+
if (pageY + height > (document.documentElement.clientHeight - margin)) return null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
...options,
|
|
110
|
+
offsetX,
|
|
111
|
+
offsetY,
|
|
112
|
+
pageX,
|
|
113
|
+
pageY,
|
|
114
|
+
transformOriginX: directionX === 'center' ? 'center' : (directionX === 'left' ? 'right' : 'left'),
|
|
115
|
+
transformOriginY: directionY === 'center' ? 'center' : (directionY === 'up' ? 'bottom' : 'top'),
|
|
116
|
+
};
|
|
117
|
+
}
|