@ulu/frontend 0.1.0-beta.32 → 0.1.0-beta.34
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/CHANGELOG.md +53 -0
- package/dist/ulu-frontend.min.css +1 -1
- package/dist/ulu-frontend.min.js +23 -23
- package/docs-dev/changelog/index.html +161 -8
- package/docs-dev/demos/accordion/index.html +38 -8
- package/docs-dev/demos/button/index.html +38 -8
- package/docs-dev/demos/button-verbose/index.html +38 -8
- package/docs-dev/demos/callout/index.html +65 -8
- package/docs-dev/demos/captioned-figure/index.html +38 -8
- package/docs-dev/demos/card/index.html +59 -33
- package/docs-dev/demos/card-grid/index.html +42 -12
- package/docs-dev/demos/css-icons/index.html +38 -8
- package/docs-dev/demos/data-grid/index.html +38 -8
- package/docs-dev/demos/data-table/index.html +63 -33
- package/docs-dev/demos/details-group/index.html +71 -8
- package/docs-dev/demos/file-save/index.html +38 -8
- package/docs-dev/demos/flipcard/index.html +38 -8
- package/docs-dev/demos/form-theme/index.html +38 -8
- package/docs-dev/demos/index.html +38 -8
- package/docs-dev/demos/list-inline/index.html +38 -8
- package/docs-dev/demos/list-lines/index.html +38 -8
- package/docs-dev/demos/menu-stack/index.html +38 -8
- package/docs-dev/demos/modals/index.html +51 -10
- package/docs-dev/demos/nav-strip/index.html +38 -8
- package/docs-dev/demos/overlay-section/index.html +38 -8
- package/docs-dev/demos/popovers/index.html +38 -8
- package/docs-dev/demos/print/index.html +38 -8
- package/docs-dev/demos/pull-quote/index.html +38 -8
- package/docs-dev/demos/rule/index.html +38 -8
- package/docs-dev/demos/scrollpoints/index.html +39 -9
- package/docs-dev/demos/spoke-spinner/index.html +38 -8
- package/docs-dev/demos/sticky-list/index.html +38 -8
- package/docs-dev/demos/tabs/index.html +74 -8
- package/docs-dev/demos/tag/index.html +38 -8
- package/docs-dev/demos/theme-toggle/index.html +38 -8
- package/docs-dev/demos/tiles/index.html +38 -8
- package/docs-dev/demos/tooltip/index.html +38 -8
- package/docs-dev/guide/building-stylesheet/index.html +38 -8
- package/docs-dev/guide/developing-ulu-scss-module/index.html +38 -8
- package/docs-dev/guide/index.html +38 -8
- package/docs-dev/index.html +38 -8
- package/docs-dev/javascript/events/index.html +38 -8
- package/docs-dev/javascript/index.html +38 -8
- package/docs-dev/javascript/settings/index.html +38 -8
- package/docs-dev/javascript/ui-breakpoints/index.html +38 -8
- package/docs-dev/javascript/ui-collapsible/index.html +38 -8
- package/docs-dev/javascript/ui-details-group/index.html +56 -38
- package/docs-dev/javascript/ui-dialog/index.html +70 -25
- package/docs-dev/javascript/ui-flipcard/index.html +99 -13
- package/docs-dev/javascript/ui-grid/index.html +48 -44
- package/docs-dev/javascript/ui-modal-builder/index.html +49 -40
- package/docs-dev/javascript/ui-overflow-scroller/index.html +38 -8
- package/docs-dev/javascript/ui-overflow-scroller-pager/index.html +38 -8
- package/docs-dev/javascript/ui-page/index.html +38 -8
- package/docs-dev/javascript/ui-popover/index.html +46 -20
- package/docs-dev/javascript/ui-print/index.html +38 -16
- package/docs-dev/javascript/ui-print-details/index.html +38 -8
- package/docs-dev/javascript/ui-programmatic-modal/index.html +38 -8
- package/docs-dev/javascript/ui-proxy-click/index.html +125 -10
- package/docs-dev/javascript/ui-resizer/index.html +38 -8
- package/docs-dev/javascript/ui-scroll-slider/index.html +76 -14
- package/docs-dev/javascript/ui-scrollpoint/index.html +44 -21
- package/docs-dev/javascript/ui-slider/index.html +234 -13
- package/docs-dev/javascript/ui-tabs/index.html +49 -56
- package/docs-dev/javascript/ui-theme-toggle/index.html +43 -21
- package/docs-dev/javascript/ui-tooltip/index.html +45 -19
- package/docs-dev/javascript/utils-class-logger/index.html +38 -8
- package/docs-dev/javascript/utils-dom/index.html +63 -8
- package/docs-dev/javascript/utils-file-save/index.html +38 -8
- package/docs-dev/javascript/utils-floating-ui/index.html +38 -8
- package/docs-dev/javascript/utils-id/index.html +38 -8
- package/docs-dev/javascript/utils-pause-youtube-video/index.html +38 -8
- package/docs-dev/javascript/utils-system/index.html +5437 -0
- package/docs-dev/sass/base/color/index.html +38 -8
- package/docs-dev/sass/base/elements/index.html +38 -8
- package/docs-dev/sass/base/index/index.html +38 -8
- package/docs-dev/sass/base/index.html +38 -8
- package/docs-dev/sass/base/keyframes/index.html +38 -8
- package/docs-dev/sass/base/layout/index.html +38 -8
- package/docs-dev/sass/base/normalize/index.html +38 -8
- package/docs-dev/sass/base/print/index.html +38 -8
- package/docs-dev/sass/base/root/index.html +38 -8
- package/docs-dev/sass/base/typography/index.html +38 -8
- package/docs-dev/sass/components/accordion/index.html +39 -9
- package/docs-dev/sass/components/adaptive-spacing/index.html +38 -8
- package/docs-dev/sass/components/badge/index.html +38 -8
- package/docs-dev/sass/components/basic-hero/index.html +38 -8
- package/docs-dev/sass/components/button/index.html +38 -8
- package/docs-dev/sass/components/button-verbose/index.html +72 -37
- package/docs-dev/sass/components/callout/index.html +124 -35
- package/docs-dev/sass/components/captioned-figure/index.html +38 -8
- package/docs-dev/sass/components/card/index.html +38 -8
- package/docs-dev/sass/components/card-grid/index.html +38 -8
- package/docs-dev/sass/components/css-icon/index.html +38 -8
- package/docs-dev/sass/components/data-grid/index.html +38 -8
- package/docs-dev/sass/components/data-table/index.html +53 -16
- package/docs-dev/sass/components/fill-context/index.html +38 -8
- package/docs-dev/sass/components/flipcard/index.html +38 -8
- package/docs-dev/sass/components/flipcard-grid/index.html +38 -8
- package/docs-dev/sass/components/form-theme/index.html +84 -60
- package/docs-dev/sass/components/hero/index.html +38 -8
- package/docs-dev/sass/components/horizontal-rule/index.html +38 -8
- package/docs-dev/sass/components/image-grid/index.html +38 -8
- package/docs-dev/sass/components/index/index.html +38 -8
- package/docs-dev/sass/components/index.html +38 -8
- package/docs-dev/sass/components/links/index.html +38 -8
- package/docs-dev/sass/components/list-inline/index.html +38 -8
- package/docs-dev/sass/components/list-lines/index.html +38 -8
- package/docs-dev/sass/components/list-ordered/index.html +38 -8
- package/docs-dev/sass/components/list-unordered/index.html +38 -8
- package/docs-dev/sass/components/menu-stack/index.html +38 -8
- package/docs-dev/sass/components/modal/index.html +38 -8
- package/docs-dev/sass/components/nav-strip/index.html +38 -8
- package/docs-dev/sass/components/overlay-section/index.html +38 -8
- package/docs-dev/sass/components/pager/index.html +38 -8
- package/docs-dev/sass/components/placeholder-block/index.html +38 -8
- package/docs-dev/sass/components/popover/index.html +38 -8
- package/docs-dev/sass/components/pull-quote/index.html +38 -8
- package/docs-dev/sass/components/ratio-box/index.html +38 -8
- package/docs-dev/sass/components/rule/index.html +38 -8
- package/docs-dev/sass/components/scroll-slider/index.html +46 -28
- package/docs-dev/sass/components/skip-link/index.html +38 -8
- package/docs-dev/sass/components/slider/index.html +38 -8
- package/docs-dev/sass/components/spoke-spinner/index.html +40 -10
- package/docs-dev/sass/components/sticky-list/index.html +38 -8
- package/docs-dev/sass/components/tabs/index.html +38 -8
- package/docs-dev/sass/components/tag/index.html +40 -10
- package/docs-dev/sass/components/tile-button/index.html +38 -8
- package/docs-dev/sass/components/tile-grid/index.html +38 -8
- package/docs-dev/sass/components/tile-grid-overlay/index.html +38 -8
- package/docs-dev/sass/components/vignette/index.html +38 -8
- package/docs-dev/sass/components/wysiwyg/index.html +38 -8
- package/docs-dev/sass/core/breakpoint/index.html +38 -8
- package/docs-dev/sass/core/button/index.html +38 -8
- package/docs-dev/sass/core/color/index.html +38 -8
- package/docs-dev/sass/core/cssvar/index.html +38 -8
- package/docs-dev/sass/core/element/index.html +218 -47
- package/docs-dev/sass/core/index.html +38 -8
- package/docs-dev/sass/core/layout/index.html +94 -45
- package/docs-dev/sass/core/path/index.html +38 -8
- package/docs-dev/sass/core/selector/index.html +38 -8
- package/docs-dev/sass/core/typography/index.html +38 -8
- package/docs-dev/sass/core/units/index.html +38 -8
- package/docs-dev/sass/core/utils/index.html +302 -68
- package/docs-dev/sass/helpers/color/index.html +38 -8
- package/docs-dev/sass/helpers/display/index.html +38 -8
- package/docs-dev/sass/helpers/index/index.html +38 -8
- package/docs-dev/sass/helpers/index.html +38 -8
- package/docs-dev/sass/helpers/print/index.html +38 -8
- package/docs-dev/sass/helpers/typography/index.html +38 -8
- package/docs-dev/sass/helpers/units/index.html +38 -8
- package/docs-dev/sass/helpers/utilities/index.html +38 -8
- package/docs-dev/sass/index.html +38 -8
- package/js/ui/breakpoints.js +1 -2
- package/js/ui/details-group.js +33 -42
- package/js/ui/dialog.js +64 -41
- package/js/ui/dialog.todo +2 -36
- package/js/ui/flipcard.js +37 -57
- package/js/ui/grid.js +15 -13
- package/js/ui/modal-builder.js +24 -38
- package/js/ui/popover.js +38 -39
- package/js/ui/print.js +16 -25
- package/js/ui/proxy-click.js +50 -36
- package/js/ui/scroll-slider.js +24 -30
- package/js/ui/scrollpoint.js +27 -63
- package/js/ui/slider.js +53 -55
- package/js/ui/tabs.js +23 -36
- package/js/ui/theme-toggle.js +37 -41
- package/js/ui/tooltip.js +27 -32
- package/js/utils/dom.js +12 -0
- package/js/utils/system.js +154 -0
- package/package.json +1 -1
- package/scss/_element.scss +91 -0
- package/scss/_layout.scss +3 -1
- package/scss/_utils.scss +42 -0
- package/scss/components/_accordion.scss +1 -2
- package/scss/components/_button-verbose.scss +41 -36
- package/scss/components/_callout.scss +113 -53
- package/scss/components/_data-table.scss +3 -0
- package/scss/components/_form-theme.scss +24 -25
- package/scss/components/_scroll-slider.scss +0 -4
- package/types/ui/breakpoints.d.ts.map +1 -1
- package/types/ui/details-group.d.ts +7 -12
- package/types/ui/details-group.d.ts.map +1 -1
- package/types/ui/dialog.d.ts +19 -14
- package/types/ui/dialog.d.ts.map +1 -1
- package/types/ui/flipcard.d.ts +16 -10
- package/types/ui/flipcard.d.ts.map +1 -1
- package/types/ui/grid.d.ts +4 -6
- package/types/ui/grid.d.ts.map +1 -1
- package/types/ui/modal-builder.d.ts +5 -9
- package/types/ui/modal-builder.d.ts.map +1 -1
- package/types/ui/popover.d.ts +6 -7
- package/types/ui/popover.d.ts.map +1 -1
- package/types/ui/print.d.ts +0 -4
- package/types/ui/print.d.ts.map +1 -1
- package/types/ui/proxy-click.d.ts +19 -3
- package/types/ui/proxy-click.d.ts.map +1 -1
- package/types/ui/scroll-slider.d.ts +5 -7
- package/types/ui/scroll-slider.d.ts.map +1 -1
- package/types/ui/scrollpoint.d.ts +3 -8
- package/types/ui/scrollpoint.d.ts.map +1 -1
- package/types/ui/slider.d.ts +22 -12
- package/types/ui/slider.d.ts.map +1 -1
- package/types/ui/tabs.d.ts +6 -8
- package/types/ui/tabs.d.ts.map +1 -1
- package/types/ui/theme-toggle.d.ts +6 -13
- package/types/ui/theme-toggle.d.ts.map +1 -1
- package/types/ui/tooltip.d.ts +3 -5
- package/types/ui/tooltip.d.ts.map +1 -1
- package/types/utils/dom.d.ts +6 -0
- package/types/utils/dom.d.ts.map +1 -1
- package/types/utils/system.d.ts +113 -0
- package/types/utils/system.d.ts.map +1 -0
package/js/utils/dom.js
CHANGED
|
@@ -5,6 +5,18 @@
|
|
|
5
5
|
|
|
6
6
|
export const regexJsonString = /^[{\[][\s\S]*[}\]]$/;
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Converts a data attribute name to its corresponding dataset property name.
|
|
10
|
+
* @param {string} dataAttribute - The data attribute name (e.g., "data-ulu-dialog").
|
|
11
|
+
* @returns {string} - The dataset property name (e.g., "uluDialog").
|
|
12
|
+
*/
|
|
13
|
+
export function dataAttributeToDatasetKey(attribute) {
|
|
14
|
+
// Remove "data-" prefix then convert kebab-case to camelCase
|
|
15
|
+
return attribute
|
|
16
|
+
.replace(/^data-/, "")
|
|
17
|
+
.replace(/-([a-z])/g, (_match, letter) => letter.toUpperCase());
|
|
18
|
+
}
|
|
19
|
+
|
|
8
20
|
/**
|
|
9
21
|
* Get an elements JSON dataset value
|
|
10
22
|
* @param {Node} element
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module utils/system
|
|
3
|
+
* @description Core classes and mechanisms that define how UI components are created and managed within the library
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { hasRequiredProps } from "@ulu/utils/object.js";
|
|
7
|
+
import { getDatasetOptionalJson, dataAttributeToDatasetKey } from "./dom.js";
|
|
8
|
+
import { getName } from "../events/index.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Class serves as a utility for UI modules, handling the selection of elements and the initialization of corresponding component instances, ensuring consistent setup within the module
|
|
12
|
+
*/
|
|
13
|
+
export class ComponentInitializer {
|
|
14
|
+
static defaults = {
|
|
15
|
+
type: null,
|
|
16
|
+
baseAttribute: null
|
|
17
|
+
};
|
|
18
|
+
static requiredOptions = [
|
|
19
|
+
"type",
|
|
20
|
+
"baseAttribute"
|
|
21
|
+
];
|
|
22
|
+
static hasRequiredOptions = hasRequiredProps(
|
|
23
|
+
ComponentInitializer.requiredOptions
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Create a new instance of ComponentInitializer
|
|
28
|
+
* @param {Object} options Options for configuring the component initializer.
|
|
29
|
+
* @param {String} options.type Type of component (used for logs).
|
|
30
|
+
* @param {String} options.baseAttribute Prefix and base attribute name (used for base attribute and further element attribute names).
|
|
31
|
+
*/
|
|
32
|
+
constructor(options) {
|
|
33
|
+
if (!ComponentInitializer.hasRequiredOptions(options)) {
|
|
34
|
+
throw new Error(
|
|
35
|
+
`Missing a required options: ${ ComponentInitializer.requiredOptions.join(", ") }`
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
this.options = Object.assign({}, ComponentInitializer.defaults, options);
|
|
39
|
+
this.logTitle = `ULU: ${ this.options.type }:\n`;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Initializes the component based on the provided configuration.
|
|
43
|
+
* @param {Object} config The initialization configuration.
|
|
44
|
+
* @param {Function} config.setup The setup function to call for each element.
|
|
45
|
+
* @param {String} config.key [null] The optional key to use with attribute selector.
|
|
46
|
+
* @param {Boolean} config.withData [null] Whether to retrieve element data.
|
|
47
|
+
* @param {Array} config.events [null] Ulu events that should call setup when dispatched (ie. pageModified, pageResized)
|
|
48
|
+
* @param {Boolean} config.onPageResized [null] Whether to bind event listener for page resize end
|
|
49
|
+
* @param {HTMLElement} config.context [document] The context to query within.
|
|
50
|
+
*/
|
|
51
|
+
init(config) {
|
|
52
|
+
this.setupElements(config);
|
|
53
|
+
// Attach Handler to reinitialize if page is updated
|
|
54
|
+
// Specifically checking entire document incase element that dispatched
|
|
55
|
+
// event made alterations outside of itself
|
|
56
|
+
if (config.events?.length) {
|
|
57
|
+
config.events.forEach(name => {
|
|
58
|
+
document.addEventListener(getName(name), () => this.setupElements(config));
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Processes the elements based on the provided configuration.
|
|
64
|
+
* @param {object} config The initialization configuration.
|
|
65
|
+
* @param {function} config.setup The setup function to call for each element.
|
|
66
|
+
* @param {string} config.key The optional key to use with attribute selector.
|
|
67
|
+
* @param {boolean} config.withData [false] Whether to retrieve element data.
|
|
68
|
+
* @param {boolean} config.onPageModified [true] Whether to bind event listener for page modifications.
|
|
69
|
+
* @param {HTMLElement} config.context [document] The context to query within.
|
|
70
|
+
*/
|
|
71
|
+
setupElements(config) {
|
|
72
|
+
const { setup, key, withData, context } = config;
|
|
73
|
+
const elementsWithData = this.queryAllInitial(key, withData, context);
|
|
74
|
+
elementsWithData.forEach(elementWithData => setup(elementWithData, this));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get an attribute name
|
|
78
|
+
* @param {String} key Optional key, if no key will return baseAttribute if key will return key added to base
|
|
79
|
+
* @returns {String} String like data-ulu-dialog or data-ulu-dialog-element
|
|
80
|
+
*/
|
|
81
|
+
getAttribute(key) {
|
|
82
|
+
const { baseAttribute } = this.options;
|
|
83
|
+
return key ? `${ baseAttribute }-${ key }` : `${ baseAttribute }`;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Create an attribute selector
|
|
87
|
+
* @param {String} key Optional key (see getAttribute)
|
|
88
|
+
*/
|
|
89
|
+
attributeSelector(key) {
|
|
90
|
+
return `[${ this.getAttribute(key) }]`;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Create an attribute selector for initial
|
|
94
|
+
* @return {String}
|
|
95
|
+
*/
|
|
96
|
+
attributeSelectorInitial(key) {
|
|
97
|
+
return `${ this.attributeSelector(key) }:not([${ this.getAttribute("init") }])`
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Queries all main elements of a component that have not been initialized and extracts their data attributes.
|
|
101
|
+
* @param {HTMLElement} context The context to query within.
|
|
102
|
+
* @param {Boolean} withData Include dataset from element (as optional JSON)
|
|
103
|
+
* @param {Node} context Element to query elements from
|
|
104
|
+
* @returns {Array<{element: HTMLElement, data: object, initialize: Function}>} An array of objects containing the elements, their data, and convenience function initialize() which when called will set the init attribute on the element
|
|
105
|
+
*/
|
|
106
|
+
queryAllInitial(key, withData, context = document) {
|
|
107
|
+
const elements = [ ...context.querySelectorAll(this.attributeSelectorInitial(key)) ];
|
|
108
|
+
return elements.map((element) => ({
|
|
109
|
+
element,
|
|
110
|
+
data: withData ? this.getData(element, key) : null,
|
|
111
|
+
initialize: () => this.initializeElement(element)
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Sets the init attribute on an element, marking it as initialized.
|
|
116
|
+
* @param {HTMLElement} element The element to initialize.
|
|
117
|
+
*/
|
|
118
|
+
initializeElement(element) {
|
|
119
|
+
element.setAttribute(this.getAttribute("init"), "");
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get an elements dataset value as JSON or other value
|
|
123
|
+
* @return {*} The value of the dataset, if JSON will return object else will return string value or undefined
|
|
124
|
+
*/
|
|
125
|
+
getData(element, key) {
|
|
126
|
+
const datasetKey = dataAttributeToDatasetKey(this.getAttribute(key));
|
|
127
|
+
return getDatasetOptionalJson(element, datasetKey);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Will output namespaced console logs for the given initializer
|
|
131
|
+
*/
|
|
132
|
+
log(...msgs) {
|
|
133
|
+
console.log(this.logTitle, ...msgs);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Will output namespaced console warnings for the given initializer
|
|
137
|
+
*/
|
|
138
|
+
warn(...msgs) {
|
|
139
|
+
console.warn(this.logTitle, ...msgs);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Will output namespaced console error for the given initializer
|
|
143
|
+
*/
|
|
144
|
+
logError(...msgs) {
|
|
145
|
+
console.error(this.logTitle, ...msgs);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Class serves as a base for representing individual occurrences of a UI component, providing a consistent structure for each
|
|
151
|
+
*/
|
|
152
|
+
export class ComponentInstance {
|
|
153
|
+
|
|
154
|
+
}
|
package/package.json
CHANGED
package/scss/_element.scss
CHANGED
|
@@ -69,6 +69,8 @@ $config: (
|
|
|
69
69
|
"ul-list-style-type": disc,
|
|
70
70
|
"ul-list-style-type-2": circle,
|
|
71
71
|
"ul-list-style-type-3": square,
|
|
72
|
+
"cap-color" : "accent",
|
|
73
|
+
"cap-size" : 5px
|
|
72
74
|
) !default;
|
|
73
75
|
|
|
74
76
|
/// Rule style map, redefine defaults or add to
|
|
@@ -290,4 +292,93 @@ $rule-margins: (
|
|
|
290
292
|
white-space: normal;
|
|
291
293
|
width: auto;
|
|
292
294
|
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
/// Layout utility to add a colored bar (cap) to an element's edge, positioned over the element and its border
|
|
299
|
+
/// - You need to set position (relative, fixed) on parent
|
|
300
|
+
/// @param {String} $side The side to place the cap (top, bottom, left, right)
|
|
301
|
+
/// @param {Map} $options Options for the appearance of the cap
|
|
302
|
+
/// @param {Color} $options.color [$config.cap-color] The color for the end cap
|
|
303
|
+
/// @param {Number} $options.size [$config.cap-size] The width/height of the cap
|
|
304
|
+
/// @param {Number} $options.offset [0] A positive number of the amount the cap should extend outside the box (to account for border-width)
|
|
305
|
+
/// @param {Number} $options.border-radius [null] An optional border-radius to apply to the outward-facing edges of the cap (used to match parent)
|
|
306
|
+
/// @param {Boolean} $before [true] Whether or not to use the ::before element (if not uses :after)
|
|
307
|
+
|
|
308
|
+
@mixin cap(
|
|
309
|
+
$side,
|
|
310
|
+
$options: (),
|
|
311
|
+
$before: true,
|
|
312
|
+
) {
|
|
313
|
+
$defaults: (
|
|
314
|
+
"color" : get("cap-color"),
|
|
315
|
+
"size" : get("cap-size"),
|
|
316
|
+
"offset" : 0,
|
|
317
|
+
"color-hover" : null,
|
|
318
|
+
"border-radius" : null,
|
|
319
|
+
"padding-adjust" : null,
|
|
320
|
+
);
|
|
321
|
+
$config: map.merge($defaults, $options);
|
|
322
|
+
$element: if($before, "::before", "::after");
|
|
323
|
+
|
|
324
|
+
&#{ $element } {
|
|
325
|
+
content: "";
|
|
326
|
+
position: absolute;
|
|
327
|
+
display: block;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
@include cap-appearance($side, $config, $before);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
/// Provides the appearance styles for a given cap
|
|
336
|
+
/// - If an option is not provided it won't be output
|
|
337
|
+
/// - This is used to update the caps styling (states, modifiers, etc)
|
|
338
|
+
/// @param {String} $side The side to place the cap (top, bottom, left, right)
|
|
339
|
+
/// @param {Map} $options Options for the appearance of the cap (see options from element.cap)
|
|
340
|
+
/// @param {Boolean} $before Whether or not to use the ::before element (if not uses :after)
|
|
341
|
+
|
|
342
|
+
@mixin cap-appearance(
|
|
343
|
+
$side,
|
|
344
|
+
$options: (),
|
|
345
|
+
$before: true
|
|
346
|
+
) {
|
|
347
|
+
$element: if($before, "::before", "::after");
|
|
348
|
+
$size: map.get($options, "size");
|
|
349
|
+
$offset: map.get($options, "offset");
|
|
350
|
+
$border-radius: map.get($options, "border-radius");
|
|
351
|
+
$padding-adjust: map.get($options, "padding-adjust");
|
|
352
|
+
|
|
353
|
+
$end: $side == "top" or $side == "bottom";
|
|
354
|
+
$position: if($offset, 0 - $offset, null);
|
|
355
|
+
|
|
356
|
+
@if ($padding-adjust and $size) {
|
|
357
|
+
padding-#{ $side }: calc($padding-adjust + $size);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
&#{ $element } {
|
|
361
|
+
background-color: color.get(map.get($options, "color"));
|
|
362
|
+
#{ $side }: $position;
|
|
363
|
+
|
|
364
|
+
@if $end {
|
|
365
|
+
left: $position;
|
|
366
|
+
right: $position;
|
|
367
|
+
height: $size;
|
|
368
|
+
} @else {
|
|
369
|
+
top: $position;
|
|
370
|
+
bottom: $position;
|
|
371
|
+
width: $size;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
@if $border-radius {
|
|
375
|
+
@if $end {
|
|
376
|
+
border-#{ $side }-left-radius: $border-radius;
|
|
377
|
+
border-#{ $side }-right-radius: $border-radius;
|
|
378
|
+
} @else {
|
|
379
|
+
border-top-#{ $side }-radius: $border-radius;
|
|
380
|
+
border-bottom-#{ $side }-radius: $border-radius;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
293
384
|
}
|
package/scss/_layout.scss
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
@use "sass:meta";
|
|
8
8
|
@use "utils";
|
|
9
9
|
@use "breakpoint";
|
|
10
|
+
@use "color";
|
|
10
11
|
|
|
11
12
|
/// Module Settings
|
|
12
13
|
/// @type Map
|
|
@@ -264,6 +265,7 @@ $containers: (
|
|
|
264
265
|
/// Layout utility for absolute (zero on all sides)
|
|
265
266
|
/// - Probably helpful for gzip if we use this when these exact styles are needed
|
|
266
267
|
/// so they are identical for compression
|
|
268
|
+
/// @param {Boolean} $set-size [false] Whether or not to use sizes to fill the space (height/width 100%) versus setting bottom and right to 0)
|
|
267
269
|
@mixin absolute-fill($set-size: false) {
|
|
268
270
|
position: absolute;
|
|
269
271
|
top: 0;
|
|
@@ -275,4 +277,4 @@ $containers: (
|
|
|
275
277
|
width: 100%;
|
|
276
278
|
height: 100%;
|
|
277
279
|
}
|
|
278
|
-
}
|
|
280
|
+
}
|
package/scss/_utils.scss
CHANGED
|
@@ -161,6 +161,16 @@ $config: (
|
|
|
161
161
|
@return $number + string.unquote($unit);
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
+
/// Checks if two numbers are the same unit
|
|
165
|
+
/// @param {Number} $number
|
|
166
|
+
/// @param {String} $other-number
|
|
167
|
+
/// @return {Boolean} Whether they have the same unit type
|
|
168
|
+
// Could be made into multiple arguments in future if needed
|
|
169
|
+
|
|
170
|
+
@function units-match($number, $other-number) {
|
|
171
|
+
@return math.unit($number) == math.unit($other-number);
|
|
172
|
+
}
|
|
173
|
+
|
|
164
174
|
/// Reusable merge method
|
|
165
175
|
/// @param {Map} $original Source map
|
|
166
176
|
/// @param {Map} $changes Changes to merge into source map
|
|
@@ -661,4 +671,36 @@ $config: (
|
|
|
661
671
|
|
|
662
672
|
@function is-odd($number) {
|
|
663
673
|
@return not is-even($number);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/// Always returns a map
|
|
677
|
+
/// @param {*} $value The value to check if is map
|
|
678
|
+
/// @return {Map} The $value if it was a map, else empty map
|
|
679
|
+
|
|
680
|
+
@function ensure-map($value) {
|
|
681
|
+
@return if(is-map($value), $value, ());
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/// Returns true if edge passed is an end (top/bottom)
|
|
685
|
+
/// @param {String} $edge The edge string to test
|
|
686
|
+
/// @return {Boolean} Whether the edge was an end (versus side/x-axis)
|
|
687
|
+
/// @throw If $edge is not a valid value (not top/bottom/left/right)
|
|
688
|
+
|
|
689
|
+
@function is-end($edge) {
|
|
690
|
+
@if ($edge == "top" or $edge == "bottom") {
|
|
691
|
+
@return true;
|
|
692
|
+
} @else if ($edge == "left" or $edge == "right") {
|
|
693
|
+
@return false;
|
|
694
|
+
} @else {
|
|
695
|
+
@error "Expected side to be top/bottom/left/right, got #{ $edge }";
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/// Returns true if edge passed is an side (left/right)
|
|
700
|
+
/// @param {String} $edge The edge string to test
|
|
701
|
+
/// @return {Boolean} Whether the edge was an side (versus end/y-axis)
|
|
702
|
+
/// @throw If $edge is not a valid value (not top/bottom/left/right)
|
|
703
|
+
|
|
704
|
+
@function is-side($edge) {
|
|
705
|
+
@return not is-end($edge);
|
|
664
706
|
}
|
|
@@ -120,7 +120,7 @@ $config: (
|
|
|
120
120
|
& + & {
|
|
121
121
|
$gap: -(get("margin") - get("margin-between"));
|
|
122
122
|
margin-top: $gap;
|
|
123
|
-
margin-top: calc($gap -
|
|
123
|
+
margin-top: calc($gap - get("border-width"));
|
|
124
124
|
}
|
|
125
125
|
&[open],
|
|
126
126
|
&.is-active {
|
|
@@ -208,7 +208,6 @@ $config: (
|
|
|
208
208
|
}
|
|
209
209
|
#{ $prefix }--no-borders {
|
|
210
210
|
border: none;
|
|
211
|
-
margin-bottom: 4rem;
|
|
212
211
|
&[open] > .accordion__summary {
|
|
213
212
|
border-bottom: none;
|
|
214
213
|
}
|
|
@@ -48,11 +48,11 @@ $-fallbacks: (
|
|
|
48
48
|
/// @prop {String} title-color [link] Color of the title of the button.
|
|
49
49
|
/// @prop {String} title-color-hover [link-hover] Color of the title of the button when hovered or focused.
|
|
50
50
|
/// @prop {Dimension} title-margin [0.5em] Margin for the button's title.
|
|
51
|
-
/// @prop {Boolean}
|
|
52
|
-
/// @prop {Color}
|
|
53
|
-
/// @prop {
|
|
54
|
-
/// @prop {
|
|
55
|
-
/// @prop {
|
|
51
|
+
/// @prop {Boolean} cap [false] Enable left cap style
|
|
52
|
+
/// @prop {Color} cap-side ["left"] The side that gets the cap
|
|
53
|
+
/// @prop {Number} cap-match-radius [true] The cap should have be rounded to match the parent's border radius
|
|
54
|
+
/// @prop {Map} cap-options The options for cap (see element.cap for options)
|
|
55
|
+
/// @prop {Map} cap-options-hover The options for cap when hovered
|
|
56
56
|
|
|
57
57
|
$config: (
|
|
58
58
|
"background-color" : white,
|
|
@@ -69,16 +69,21 @@ $config: (
|
|
|
69
69
|
"margin" : 1em,
|
|
70
70
|
"margin-inline" : 0.75em,
|
|
71
71
|
"min-width": 20rem,
|
|
72
|
-
"padding-x": 0.
|
|
72
|
+
"padding-x": 0.75em,
|
|
73
73
|
"padding-y": 1em,
|
|
74
74
|
"title-color": "link",
|
|
75
75
|
"title-margin" : 0.5em,
|
|
76
76
|
"title-color-hover" : "link-hover",
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
|
|
77
|
+
"cap" : false,
|
|
78
|
+
"cap-side" : "left",
|
|
79
|
+
"cap-match-radius" : true,
|
|
80
|
+
"cap-options" : (
|
|
81
|
+
"color" : "link",
|
|
82
|
+
"size" : 0.5rem,
|
|
83
|
+
),
|
|
84
|
+
"cap-options-hover" : (
|
|
85
|
+
"color" : "link-hover"
|
|
86
|
+
),
|
|
82
87
|
) !default;
|
|
83
88
|
|
|
84
89
|
/// Change modules $config
|
|
@@ -112,40 +117,30 @@ $config: (
|
|
|
112
117
|
|
|
113
118
|
@mixin styles {
|
|
114
119
|
$prefix: selector.class("button-verbose");
|
|
120
|
+
$padding-x: get("padding-x");
|
|
121
|
+
$padding-y: get("padding-y");
|
|
122
|
+
$padding-right: ($padding-x * 2) + 1em;
|
|
123
|
+
$cap-side: get("cap-side");
|
|
124
|
+
$cap-defaults: (
|
|
125
|
+
"border-radius" : if(get("cap-match-radius"), get("border-radius"), 0),
|
|
126
|
+
"padding-adjust" : if(utils.is-side($cap-side), $padding-x, $padding-y)
|
|
127
|
+
);
|
|
115
128
|
|
|
116
129
|
#{ $prefix } {
|
|
117
130
|
text-decoration: none;
|
|
118
131
|
border-radius: get("border-radius");
|
|
119
132
|
box-shadow: get("box-shadow");
|
|
120
133
|
line-height: get("line-height");
|
|
121
|
-
position: relative;
|
|
134
|
+
position: relative; // For cap and icon
|
|
122
135
|
display: block;
|
|
123
136
|
margin-bottom: get("margin");
|
|
124
137
|
max-width: 100%;
|
|
125
138
|
width: get("min-width");
|
|
126
139
|
background-color: color.get(get("background-color"));
|
|
127
|
-
padding:
|
|
128
|
-
padding-right: (get("padding-x") * 2) + 1em;
|
|
140
|
+
padding: $padding-y $padding-right $padding-y $padding-x;
|
|
129
141
|
color: color.get(get("color"));
|
|
130
142
|
text-align: left;
|
|
131
|
-
|
|
132
|
-
@if get("left-cap") {
|
|
133
|
-
padding-left: calc(get("padding-x") + get("left-cap-width"));
|
|
134
|
-
&::after {
|
|
135
|
-
content: "";
|
|
136
|
-
display: block;
|
|
137
|
-
position: absolute;
|
|
138
|
-
top: 0;
|
|
139
|
-
bottom: 0;
|
|
140
|
-
left: 0;
|
|
141
|
-
width: get("left-cap-width");
|
|
142
|
-
background-color: color.get(get("left-cap-color"));
|
|
143
|
-
@if get("left-cap-match-radius") {
|
|
144
|
-
border-top-left-radius: get("border-radius");
|
|
145
|
-
border-bottom-left-radius: get("border-radius");
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
143
|
+
|
|
149
144
|
&:hover {
|
|
150
145
|
color: color.get(get("color-hover"));
|
|
151
146
|
background-color: color.get(get("background-color-hover"));
|
|
@@ -160,9 +155,19 @@ $config: (
|
|
|
160
155
|
color: color.get(get("icon-color-hover"));
|
|
161
156
|
}
|
|
162
157
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
158
|
+
}
|
|
159
|
+
@if get("cap") {
|
|
160
|
+
@include element.cap(
|
|
161
|
+
$side: $cap-side,
|
|
162
|
+
$options: map.merge($cap-defaults, get("cap-options"))
|
|
163
|
+
);
|
|
164
|
+
@if get("cap-options-hover") {
|
|
165
|
+
&:hover,
|
|
166
|
+
&:focus {
|
|
167
|
+
@include element.cap-appearance(
|
|
168
|
+
$side: $cap-side,
|
|
169
|
+
$options: get("cap-options-hover")
|
|
170
|
+
);
|
|
166
171
|
}
|
|
167
172
|
}
|
|
168
173
|
}
|
|
@@ -180,7 +185,7 @@ $config: (
|
|
|
180
185
|
#{ $prefix }__icon {
|
|
181
186
|
position: absolute;
|
|
182
187
|
top: 50%;
|
|
183
|
-
right:
|
|
188
|
+
right: $padding-x;
|
|
184
189
|
transform: translateY(-50%);
|
|
185
190
|
font-size: get("icon-font-size");
|
|
186
191
|
color: color.get(get("icon-color"));
|