@dynamic-framework/ui-react 2.6.0 → 2.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/dist/css/dynamic-ui.css +7 -3
- package/dist/css/dynamic-ui.min.css +2 -2
- package/dist/index.esm.js +72 -17
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +70 -15
- package/dist/index.js.map +1 -1
- package/dist/types/components/DCarousel/DCarousel.d.ts +9 -2
- package/dist/types/components/DIcon/DIcon.d.ts +4 -4
- package/dist/types/components/DIconBase/DIconBase.d.ts +3 -2
- package/dist/types/components/DIconBase/index.d.ts +1 -0
- package/dist/types/components/DOffcanvas/DOffcanvas.d.ts +15 -3
- package/dist/types/components/interface.d.ts +5 -3
- package/dist/types/contexts/DContext.d.ts +3 -2
- package/package.json +3 -1
- package/src/style/abstracts/variables/_offcanvas.scss +8 -0
- package/src/style/components/_d-carousel.scss +19 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
|
-
import React, { useEffect, useState, useCallback, useMemo, useContext, createContext, useLayoutEffect, useSyncExternalStore, forwardRef, useId, useRef, isValidElement, cloneElement, createRef } from 'react';
|
|
3
|
+
import React, { useEffect, useState, useCallback, useMemo, useContext, createContext, useLayoutEffect, useSyncExternalStore, createElement, forwardRef, useId, useRef, isValidElement, cloneElement, createRef } from 'react';
|
|
4
4
|
import { __rest } from 'tslib';
|
|
5
5
|
import * as LucideIcons from 'lucide-react';
|
|
6
|
+
import { isValidElementType } from 'react-is';
|
|
6
7
|
import { createPortal } from 'react-dom';
|
|
7
8
|
import { AnimatePresence, motion } from 'framer-motion';
|
|
8
9
|
import { fromEvent } from 'file-selector';
|
|
9
|
-
import { SplideSlide, Splide } from '@splidejs/react-splide';
|
|
10
|
+
import { SplideSlide, Splide, SplideTrack } from '@splidejs/react-splide';
|
|
10
11
|
import currency from 'currency.js';
|
|
11
12
|
import DatePicker from 'react-datepicker';
|
|
12
13
|
import { getYear, format, getMonth } from 'date-fns';
|
|
@@ -309,6 +310,7 @@ const DEFAULT_STATE = {
|
|
|
309
310
|
familyPrefix: 'bi-',
|
|
310
311
|
materialStyle: false,
|
|
311
312
|
},
|
|
313
|
+
iconRegistry: undefined,
|
|
312
314
|
iconMap: {
|
|
313
315
|
x: 'X',
|
|
314
316
|
xLg: 'X',
|
|
@@ -374,11 +376,12 @@ const DContext = createContext(DEFAULT_STATE);
|
|
|
374
376
|
* @template T - Map of portal name → payload shape (e.g. `{ modal: { title: string } }`).
|
|
375
377
|
* Pass it once at the top level: `<DContextProvider<MyPortals> ...>`.
|
|
376
378
|
*/
|
|
377
|
-
function DContextProvider({ language = DEFAULT_STATE.language, currency = DEFAULT_STATE.currency, icon = DEFAULT_STATE.icon, iconMap = DEFAULT_STATE.iconMap, portalName = 'd-portal', availablePortals, children, }) {
|
|
379
|
+
function DContextProvider({ language = DEFAULT_STATE.language, currency = DEFAULT_STATE.currency, icon = DEFAULT_STATE.icon, iconRegistry = DEFAULT_STATE.iconRegistry, iconMap = DEFAULT_STATE.iconMap, portalName = 'd-portal', availablePortals, children, }) {
|
|
378
380
|
const [internalContext, setInternalContext,] = useState({
|
|
379
381
|
language,
|
|
380
382
|
currency,
|
|
381
383
|
icon,
|
|
384
|
+
iconRegistry,
|
|
382
385
|
iconMap,
|
|
383
386
|
breakpoints: DEFAULT_STATE.breakpoints,
|
|
384
387
|
});
|
|
@@ -495,17 +498,21 @@ function useResponsiveProp(useListener = false) {
|
|
|
495
498
|
return { responsivePropValue };
|
|
496
499
|
}
|
|
497
500
|
|
|
501
|
+
function isIconComponent(value) {
|
|
502
|
+
return typeof value !== 'string' && isValidElementType(value);
|
|
503
|
+
}
|
|
498
504
|
function DIconBase({ icon, color, style, className, size, useListenerSize = false, hasCircle = false, materialStyle = false, familyClass, familyPrefix, strokeWidth = 2, dataAttributes, }) {
|
|
499
505
|
// If materialStyle is true, use Material Design icons (legacy)
|
|
500
|
-
const
|
|
506
|
+
const isStringIcon = typeof icon === 'string';
|
|
507
|
+
const useMaterialIcons = materialStyle && isStringIcon;
|
|
501
508
|
// Get Lucide icon component
|
|
502
509
|
const LucideIcon = useMemo(() => {
|
|
503
|
-
if (useMaterialIcons)
|
|
510
|
+
if (!isStringIcon || useMaterialIcons)
|
|
504
511
|
return null;
|
|
505
512
|
// Try to find the icon in Lucide (expects PascalCase)
|
|
506
513
|
const icons = LucideIcons;
|
|
507
514
|
return icons[icon] || null;
|
|
508
|
-
}, [icon, useMaterialIcons]);
|
|
515
|
+
}, [icon, isStringIcon, useMaterialIcons]);
|
|
509
516
|
const { responsivePropValue } = useResponsiveProp(useListenerSize);
|
|
510
517
|
const resolvedSize = useMemo(() => {
|
|
511
518
|
if (!size)
|
|
@@ -525,24 +532,35 @@ function DIconBase({ icon, color, style, className, size, useListenerSize = fals
|
|
|
525
532
|
}, [resolvedSize]);
|
|
526
533
|
// Render Material Design icon (legacy support)
|
|
527
534
|
if (useMaterialIcons) {
|
|
528
|
-
return (jsx("i", Object.assign({ className: classNames(generateClasses, familyClass), style: generateStyleVariables }, dataAttributes, { children: icon })));
|
|
535
|
+
return (jsx("i", Object.assign({ className: classNames(generateClasses, familyClass), style: generateStyleVariables }, dataAttributes, { children: isStringIcon ? icon : null })));
|
|
536
|
+
}
|
|
537
|
+
if (isIconComponent(icon)) {
|
|
538
|
+
return (jsx("span", Object.assign({ className: classNames(generateClasses), style: generateStyleVariables }, dataAttributes, { children: createElement(icon, {
|
|
539
|
+
width: resolvedSize || 24,
|
|
540
|
+
height: resolvedSize || 24,
|
|
541
|
+
strokeWidth,
|
|
542
|
+
}) })));
|
|
529
543
|
}
|
|
530
544
|
// Render Lucide icon
|
|
531
545
|
if (!LucideIcon) {
|
|
532
|
-
if (familyClass && familyPrefix) {
|
|
546
|
+
if (isStringIcon && familyClass && familyPrefix) {
|
|
533
547
|
return (jsx("i", Object.assign({ className: classNames(generateClasses, familyClass, `${familyPrefix}${icon}`), style: generateStyleVariables }, dataAttributes)));
|
|
534
548
|
}
|
|
535
549
|
// eslint-disable-next-line no-console
|
|
536
|
-
console.warn(`Icon "${icon}" not found in Lucide. Make sure to use PascalCase names (e.g., "Home", "User", "Settings")`);
|
|
550
|
+
console.warn(`Icon "${String(icon)}" not found in Lucide. Make sure to use PascalCase names (e.g., "Home", "User", "Settings")`);
|
|
537
551
|
return (jsx("span", Object.assign({ className: classNames(generateClasses), style: generateStyleVariables }, dataAttributes, { children: "?" })));
|
|
538
552
|
}
|
|
539
553
|
return (jsx("span", Object.assign({ className: classNames(generateClasses), style: generateStyleVariables }, dataAttributes, { children: jsx(LucideIcon, { size: iconSize || 24, strokeWidth: strokeWidth }) })));
|
|
540
554
|
}
|
|
541
555
|
|
|
542
556
|
function DIcon(_a) {
|
|
543
|
-
var { familyClass: propFamilyClass, familyPrefix: propFamilyPrefix, materialStyle: propMaterialStyle } = _a, props = __rest(_a, ["familyClass", "familyPrefix", "materialStyle"]);
|
|
544
|
-
const { icon: { familyClass, familyPrefix, materialStyle, }, } = useDContext();
|
|
545
|
-
|
|
557
|
+
var { icon, familyClass: propFamilyClass, familyPrefix: propFamilyPrefix, materialStyle: propMaterialStyle } = _a, props = __rest(_a, ["icon", "familyClass", "familyPrefix", "materialStyle"]);
|
|
558
|
+
const { icon: { familyClass, familyPrefix, materialStyle, }, iconRegistry, } = useDContext();
|
|
559
|
+
const registryIcon = typeof icon === 'string'
|
|
560
|
+
? iconRegistry === null || iconRegistry === void 0 ? void 0 : iconRegistry[icon]
|
|
561
|
+
: undefined;
|
|
562
|
+
const resolvedIcon = registryIcon || icon;
|
|
563
|
+
return (jsx(DIconBase, Object.assign({ icon: resolvedIcon, familyClass: propFamilyClass !== null && propFamilyClass !== void 0 ? propFamilyClass : familyClass, familyPrefix: propFamilyPrefix !== null && propFamilyPrefix !== void 0 ? propFamilyPrefix : familyPrefix, materialStyle: propMaterialStyle !== null && propMaterialStyle !== void 0 ? propMaterialStyle : materialStyle }, props)));
|
|
546
564
|
}
|
|
547
565
|
|
|
548
566
|
function DAlert({ color = 'success', icon: iconProp, iconFamilyClass, iconFamilyPrefix, iconMaterialStyle = false, iconClose: iconCloseProp, iconCloseFamilyClass, iconCloseFamilyPrefix, iconCloseMaterialStyle = false, showClose, onClose, children, id, className, style, dataAttributes, }) {
|
|
@@ -1222,8 +1240,14 @@ function DCarouselSlide(_a) {
|
|
|
1222
1240
|
return (jsx(SplideSlide, Object.assign({ className: classNames('d-carousel-slide', className) }, props)));
|
|
1223
1241
|
}
|
|
1224
1242
|
|
|
1243
|
+
const DEFAULT_ARROW_PATH = 'm15.5 0.932-4.3 4.38 14.5 14.6-14.5 14.5 4.3 4.4 14.6-14.6 4.4-4.3-4.4-4.4-14.6-14.6z';
|
|
1244
|
+
function DefaultArrowIcon() {
|
|
1245
|
+
return (jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 40 40", width: 40, height: 40, focusable: "false", "aria-hidden": "true", children: jsx("path", { d: DEFAULT_ARROW_PATH }) }));
|
|
1246
|
+
}
|
|
1225
1247
|
function DCarousel(_a, ref) {
|
|
1226
|
-
var { children, className, style, options, dataAttributes } = _a, props = __rest(_a, ["children", "className", "style", "options", "dataAttributes"]);
|
|
1248
|
+
var { children, className, style, options, dataAttributes, iconArrowLeft, iconArrowRight, hasTrack: propsHasTrack } = _a, props = __rest(_a, ["children", "className", "style", "options", "dataAttributes", "iconArrowLeft", "iconArrowRight", "hasTrack"]);
|
|
1249
|
+
// Explicit `options.arrows === false` always wins, even when icon props are set.
|
|
1250
|
+
const hasCustomArrows = Boolean((iconArrowLeft || iconArrowRight) && (options === null || options === void 0 ? void 0 : options.arrows) !== false);
|
|
1227
1251
|
return (jsx(Splide, Object.assign({ className: classNames('d-carousel', className), style: style, ref: ref, options: Object.assign(Object.assign({}, options), { classes: {
|
|
1228
1252
|
// Arrows
|
|
1229
1253
|
arrows: 'splide__arrows d-carousel-arrows',
|
|
@@ -1233,7 +1257,11 @@ function DCarousel(_a, ref) {
|
|
|
1233
1257
|
// Paginator
|
|
1234
1258
|
pagination: 'splide__pagination d-carousel-pagination',
|
|
1235
1259
|
page: 'splide__pagination__page d-carousel-pagination-page',
|
|
1236
|
-
} }) }, dataAttributes, props, {
|
|
1260
|
+
} }) }, dataAttributes, props, {
|
|
1261
|
+
// Rendering our own arrows requires taking over the track wrapper, so this
|
|
1262
|
+
// must be applied after `...props` to prevent a consumer-provided `hasTrack`
|
|
1263
|
+
// from re-enabling Splide's automatic track when custom arrows are active.
|
|
1264
|
+
hasTrack: hasCustomArrows ? false : propsHasTrack, children: hasCustomArrows ? (jsxs(Fragment, { children: [jsx(SplideTrack, { children: children }), jsxs("div", { className: "splide__arrows d-carousel-arrows", children: [jsx("button", { type: "button", className: "splide__arrow splide__arrow--prev d-carousel-arrow d-carousel-arrow-prev", children: iconArrowLeft ? jsx(DIcon, Object.assign({}, iconArrowLeft)) : jsx(DefaultArrowIcon, {}) }), jsx("button", { type: "button", className: "splide__arrow splide__arrow--next d-carousel-arrow d-carousel-arrow-next", children: iconArrowRight ? jsx(DIcon, Object.assign({}, iconArrowRight)) : jsx(DefaultArrowIcon, {}) })] })] })) : children })));
|
|
1237
1265
|
}
|
|
1238
1266
|
const ForwardedDCarousel = forwardRef(DCarousel);
|
|
1239
1267
|
ForwardedDCarousel.displayName = 'DCarousel';
|
|
@@ -2296,10 +2324,37 @@ const defaultTransition = {
|
|
|
2296
2324
|
ease: 'easeInOut',
|
|
2297
2325
|
duration: 0.3,
|
|
2298
2326
|
};
|
|
2299
|
-
function DOffcanvas({ name, className, style, staticBackdrop, scrollable, openFrom = 'end', transition, children, dataAttributes, }) {
|
|
2327
|
+
function DOffcanvas({ name, className, style, staticBackdrop, scrollable, openFrom = 'end', width, height, transition, children, dataAttributes, }) {
|
|
2328
|
+
// Only subscribe to breakpoint-change listeners when a responsive object is
|
|
2329
|
+
// actually provided, avoiding unnecessary matchMedia subscriptions for the
|
|
2330
|
+
// common case of plain string values.
|
|
2331
|
+
const hasResponsiveProp = typeof openFrom === 'object'
|
|
2332
|
+
|| typeof width === 'object'
|
|
2333
|
+
|| typeof height === 'object';
|
|
2334
|
+
const { responsivePropValue } = useResponsiveProp(hasResponsiveProp);
|
|
2335
|
+
const resolvedOpenFrom = useMemo(() => {
|
|
2336
|
+
var _a;
|
|
2337
|
+
if (typeof openFrom === 'string')
|
|
2338
|
+
return openFrom;
|
|
2339
|
+
return (_a = responsivePropValue(openFrom)) !== null && _a !== void 0 ? _a : 'end';
|
|
2340
|
+
}, [responsivePropValue, openFrom]);
|
|
2341
|
+
const resolvedWidth = useMemo(() => {
|
|
2342
|
+
if (!width)
|
|
2343
|
+
return undefined;
|
|
2344
|
+
if (typeof width === 'string')
|
|
2345
|
+
return width;
|
|
2346
|
+
return responsivePropValue(width);
|
|
2347
|
+
}, [responsivePropValue, width]);
|
|
2348
|
+
const resolvedHeight = useMemo(() => {
|
|
2349
|
+
if (!height)
|
|
2350
|
+
return undefined;
|
|
2351
|
+
if (typeof height === 'string')
|
|
2352
|
+
return height;
|
|
2353
|
+
return responsivePropValue(height);
|
|
2354
|
+
}, [responsivePropValue, height]);
|
|
2300
2355
|
return (jsx(motion.div, Object.assign({ className: classNames('offcanvas portal show', {
|
|
2301
|
-
[`offcanvas-${
|
|
2302
|
-
}, className), style: Object.assign(Object.assign({}, style), { transition: 'none' }), id: name, tabIndex: -1, "aria-labelledby": `${name}Label`, "aria-hidden": "false", custom:
|
|
2356
|
+
[`offcanvas-${resolvedOpenFrom}`]: resolvedOpenFrom,
|
|
2357
|
+
}, className), style: Object.assign(Object.assign(Object.assign(Object.assign({}, style), { transition: 'none' }), (resolvedWidth && { [`--${PREFIX_BS}offcanvas-width`]: resolvedWidth })), (resolvedHeight && { [`--${PREFIX_BS}offcanvas-height`]: resolvedHeight })), id: name, tabIndex: -1, "aria-labelledby": `${name}Label`, "aria-hidden": "false", custom: resolvedOpenFrom, variants: variants, initial: "hidden", animate: "visible", exit: "hidden", transition: Object.assign(Object.assign({}, (transition !== null && transition !== void 0 ? transition : defaultTransition)), { delay: 0.15 }) }, staticBackdrop && ({
|
|
2303
2358
|
[`data-${PREFIX_BS}backdrop`]: 'static',
|
|
2304
2359
|
[`data-${PREFIX_BS}keyboard`]: 'false',
|
|
2305
2360
|
}), scrollable && ({
|