node_modules ignore

This commit is contained in:
oier committed 2025-05-08 23:43:47 +02:00
1 parent e19d52f172
commit 4574544c9f
65041 files changed
+10593536

No files matched your search

+37
View File
@@ -0,0 +1,37 @@
Copyright (c) 2015-present Strapi Solutions SAS
Portions of the Strapi software are licensed as follows:
* All software that resides under an "ee/" directory (the “EE Software”), if that directory exists, is licensed under the license defined below.
Enterprise License
If you or the company you represent has entered into a written agreement referencing the Enterprise Edition of the Strapi source code available at
https://github.com/strapi/strapi, then such agreement applies to your use of the Enterprise Edition of the Strapi Software. If you or the company you
represent is using the Enterprise Edition of the Strapi Software in connection with a subscription to our cloud offering, then the agreement you have
agreed to with respect to our cloud offering and the licenses included in such agreement apply to your use of the Enterprise Edition of the Strapi Software.
Otherwise, the Strapi Enterprise Software License Agreement (found here https://strapi.io/enterprise-terms) applies to your use of the Enterprise Edition of the Strapi Software.
BY ACCESSING OR USING THE ENTERPRISE EDITION OF THE STRAPI SOFTWARE, YOU ARE AGREEING TO BE BOUND BY THE RELEVANT REFERENCED AGREEMENT.
IF YOU ARE NOT AUTHORIZED TO ACCEPT THESE TERMS ON BEHALF OF THE COMPANY YOU REPRESENT OR IF YOU DO NOT AGREE TO ALL OF THE RELEVANT TERMS AND CONDITIONS REFERENCED AND YOU
HAVE NOT OTHERWISE EXECUTED A WRITTEN AGREEMENT WITH STRAPI, YOU ARE NOT AUTHORIZED TO ACCESS OR USE OR ALLOW ANY USER TO ACCESS OR USE ANY PART OF
THE ENTERPRISE EDITION OF THE STRAPI SOFTWARE. YOUR ACCESS RIGHTS ARE CONDITIONAL ON YOUR CONSENT TO THE RELEVANT REFERENCED TERMS TO THE EXCLUSION OF ALL OTHER TERMS;
IF THE RELEVANT REFERENCED TERMS ARE CONSIDERED AN OFFER BY YOU, ACCEPTANCE IS EXPRESSLY LIMITED TO THE RELEVANT REFERENCED TERMS.
* All software outside of the above-mentioned directories or restrictions above is available under the "MIT Expat" license as set forth below.
MIT Expat License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+25
View File
@@ -0,0 +1,25 @@
# Strapi built-in admin panel
## Description
This is the admin panel package
## Contribute
You can read the contribution guide [here](../../../CONTRIBUTING.md)
### Setup
Create a new Strapi project: `strapi new myApp`.
Go in your project: `cd myApp`.
### Development
Start the React application: `cd myApp/admin`, then `npm start`.
The admin panel should now be available at [http://localhost:4000](http://localhost:4000).
### Build
In order to check your updates, you can build the admin panel: `cd myApp`, then `npm run build`.
+8
View File
@@ -0,0 +1,8 @@
'use strict';
var DefaultDocument = require('./admin/src/components/DefaultDocument.js');
exports.DefaultDocument = DefaultDocument.DefaultDocument;
//# sourceMappingURL=_internal.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"_internal.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
+2
View File
@@ -0,0 +1,2 @@
export { DefaultDocument } from './admin/src/components/DefaultDocument.mjs';
//# sourceMappingURL=_internal.mjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"_internal.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
+1
View File
@@ -0,0 +1 @@
export { DefaultDocument } from '../admin/src/components/DefaultDocument';
+28
View File
@@ -0,0 +1,28 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var reactRouterDom = require('react-router-dom');
var PageHelpers = require('./components/PageHelpers.js');
var Providers = require('./components/Providers.js');
var reducer = require('./reducer.js');
const App = ({ strapi, store })=>{
React.useEffect(()=>{
const language = localStorage.getItem(reducer.LANGUAGE_LOCAL_STORAGE_KEY) || 'en';
if (language) {
document.documentElement.lang = language;
}
}, []);
return /*#__PURE__*/ jsxRuntime.jsx(Providers.Providers, {
strapi: strapi,
store: store,
children: /*#__PURE__*/ jsxRuntime.jsx(React.Suspense, {
fallback: /*#__PURE__*/ jsxRuntime.jsx(PageHelpers.Page.Loading, {}),
children: /*#__PURE__*/ jsxRuntime.jsx(reactRouterDom.Outlet, {})
})
});
};
exports.App = App;
//# sourceMappingURL=App.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"App.js","sources":["../../../../admin/src/App.tsx"],"sourcesContent":["/**\n *\n * App.js\n *\n */\nimport { Suspense, useEffect } from 'react';\n\nimport { Outlet } from 'react-router-dom';\n\nimport { Page } from './components/PageHelpers';\nimport { Providers } from './components/Providers';\nimport { LANGUAGE_LOCAL_STORAGE_KEY } from './reducer';\n\nimport type { Store } from './core/store/configure';\nimport type { StrapiApp } from './StrapiApp';\n\ninterface AppProps {\n strapi: StrapiApp;\n store: Store;\n}\n\nconst App = ({ strapi, store }: AppProps) => {\n useEffect(() => {\n const language = localStorage.getItem(LANGUAGE_LOCAL_STORAGE_KEY) || 'en';\n\n if (language) {\n document.documentElement.lang = language;\n }\n }, []);\n\n return (\n <Providers strapi={strapi} store={store}>\n <Suspense fallback={<Page.Loading />}>\n <Outlet />\n </Suspense>\n </Providers>\n );\n};\n\nexport { App };\nexport type { AppProps };\n"],"names":["App","strapi","store","useEffect","language","localStorage","getItem","LANGUAGE_LOCAL_STORAGE_KEY","document","documentElement","lang","_jsx","Providers","Suspense","fallback","Page","Loading","Outlet"],"mappings":";;;;;;;;;AAqBA,MAAMA,MAAM,CAAC,EAAEC,MAAM,EAAEC,KAAK,EAAY,GAAA;IACtCC,eAAU,CAAA,IAAA;AACR,QAAA,MAAMC,QAAWC,GAAAA,YAAAA,CAAaC,OAAO,CAACC,kCAA+B,CAAA,IAAA,IAAA;AAErE,QAAA,IAAIH,QAAU,EAAA;YACZI,QAASC,CAAAA,eAAe,CAACC,IAAI,GAAGN,QAAAA;AAClC;AACF,KAAA,EAAG,EAAE,CAAA;AAEL,IAAA,qBACEO,cAACC,CAAAA,mBAAAA,EAAAA;QAAUX,MAAQA,EAAAA,MAAAA;QAAQC,KAAOA,EAAAA,KAAAA;AAChC,QAAA,QAAA,gBAAAS,cAACE,CAAAA,cAAAA,EAAAA;YAASC,QAAU,gBAAAH,cAAA,CAACI,iBAAKC,OAAO,EAAA,EAAA,CAAA;AAC/B,YAAA,QAAA,gBAAAL,cAACM,CAAAA,qBAAAA,EAAAA,EAAAA;;;AAIT;;;;"}
+26
View File
@@ -0,0 +1,26 @@
import { jsx } from 'react/jsx-runtime';
import { useEffect, Suspense } from 'react';
import { Outlet } from 'react-router-dom';
import { Page } from './components/PageHelpers.mjs';
import { Providers } from './components/Providers.mjs';
import { LANGUAGE_LOCAL_STORAGE_KEY } from './reducer.mjs';
const App = ({ strapi, store })=>{
useEffect(()=>{
const language = localStorage.getItem(LANGUAGE_LOCAL_STORAGE_KEY) || 'en';
if (language) {
document.documentElement.lang = language;
}
}, []);
return /*#__PURE__*/ jsx(Providers, {
strapi: strapi,
store: store,
children: /*#__PURE__*/ jsx(Suspense, {
fallback: /*#__PURE__*/ jsx(Page.Loading, {}),
children: /*#__PURE__*/ jsx(Outlet, {})
})
});
};
export { App };
//# sourceMappingURL=App.mjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"App.mjs","sources":["../../../../admin/src/App.tsx"],"sourcesContent":["/**\n *\n * App.js\n *\n */\nimport { Suspense, useEffect } from 'react';\n\nimport { Outlet } from 'react-router-dom';\n\nimport { Page } from './components/PageHelpers';\nimport { Providers } from './components/Providers';\nimport { LANGUAGE_LOCAL_STORAGE_KEY } from './reducer';\n\nimport type { Store } from './core/store/configure';\nimport type { StrapiApp } from './StrapiApp';\n\ninterface AppProps {\n strapi: StrapiApp;\n store: Store;\n}\n\nconst App = ({ strapi, store }: AppProps) => {\n useEffect(() => {\n const language = localStorage.getItem(LANGUAGE_LOCAL_STORAGE_KEY) || 'en';\n\n if (language) {\n document.documentElement.lang = language;\n }\n }, []);\n\n return (\n <Providers strapi={strapi} store={store}>\n <Suspense fallback={<Page.Loading />}>\n <Outlet />\n </Suspense>\n </Providers>\n );\n};\n\nexport { App };\nexport type { AppProps };\n"],"names":["App","strapi","store","useEffect","language","localStorage","getItem","LANGUAGE_LOCAL_STORAGE_KEY","document","documentElement","lang","_jsx","Providers","Suspense","fallback","Page","Loading","Outlet"],"mappings":";;;;;;;AAqBA,MAAMA,MAAM,CAAC,EAAEC,MAAM,EAAEC,KAAK,EAAY,GAAA;IACtCC,SAAU,CAAA,IAAA;AACR,QAAA,MAAMC,QAAWC,GAAAA,YAAAA,CAAaC,OAAO,CAACC,0BAA+B,CAAA,IAAA,IAAA;AAErE,QAAA,IAAIH,QAAU,EAAA;YACZI,QAASC,CAAAA,eAAe,CAACC,IAAI,GAAGN,QAAAA;AAClC;AACF,KAAA,EAAG,EAAE,CAAA;AAEL,IAAA,qBACEO,GAACC,CAAAA,SAAAA,EAAAA;QAAUX,MAAQA,EAAAA,MAAAA;QAAQC,KAAOA,EAAAA,KAAAA;AAChC,QAAA,QAAA,gBAAAS,GAACE,CAAAA,QAAAA,EAAAA;YAASC,QAAU,gBAAAH,GAAA,CAACI,KAAKC,OAAO,EAAA,EAAA,CAAA;AAC/B,YAAA,QAAA,gBAAAL,GAACM,CAAAA,MAAAA,EAAAA,EAAAA;;;AAIT;;;;"}
+379
View File
@@ -0,0 +1,379 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
require('react');
var designSystem = require('@strapi/design-system');
var invariant = require('invariant');
var isFunction = require('lodash/isFunction');
var merge = require('lodash/merge');
var pick = require('lodash/pick');
var reactRouterDom = require('react-router-dom');
var constants$1 = require('../../ee/admin/src/constants.js');
var logoStrapi2022 = require('./assets/images/logo-strapi-2022.svg.js');
var constants = require('./constants.js');
var CustomFields = require('./core/apis/CustomFields.js');
var Plugin = require('./core/apis/Plugin.js');
var rbac = require('./core/apis/rbac.js');
var router = require('./core/apis/router.js');
var Widgets = require('./core/apis/Widgets.js');
var configure = require('./core/store/configure.js');
var basename = require('./core/utils/basename.js');
var createHook = require('./core/utils/createHook.js');
var reducer = require('./reducer.js');
var router$1 = require('./router.js');
var languageNativeNames = require('./translations/languageNativeNames.js');
function _interopNamespaceDefaultOnly (e) { return Object.freeze({ __proto__: null, default: e }); }
function __variableDynamicImportRuntime1__(path) {
switch (path) {
case './translations/ar.json': return Promise.resolve().then(function () { return require('./translations/ar.json.js'); });
case './translations/ca.json': return Promise.resolve().then(function () { return require('./translations/ca.json.js'); });
case './translations/cs.json': return Promise.resolve().then(function () { return require('./translations/cs.json.js'); });
case './translations/de.json': return Promise.resolve().then(function () { return require('./translations/de.json.js'); });
case './translations/dk.json': return Promise.resolve().then(function () { return require('./translations/dk.json.js'); });
case './translations/en.json': return Promise.resolve().then(function () { return require('./translations/en.json.js'); });
case './translations/es.json': return Promise.resolve().then(function () { return require('./translations/es.json.js'); });
case './translations/eu.json': return Promise.resolve().then(function () { return require('./translations/eu.json.js'); });
case './translations/fr.json': return Promise.resolve().then(function () { return require('./translations/fr.json.js'); });
case './translations/gu.json': return Promise.resolve().then(function () { return require('./translations/gu.json.js'); });
case './translations/he.json': return Promise.resolve().then(function () { return require('./translations/he.json.js'); });
case './translations/hi.json': return Promise.resolve().then(function () { return require('./translations/hi.json.js'); });
case './translations/hu.json': return Promise.resolve().then(function () { return require('./translations/hu.json.js'); });
case './translations/id.json': return Promise.resolve().then(function () { return require('./translations/id.json.js'); });
case './translations/it.json': return Promise.resolve().then(function () { return require('./translations/it.json.js'); });
case './translations/ja.json': return Promise.resolve().then(function () { return require('./translations/ja.json.js'); });
case './translations/ko.json': return Promise.resolve().then(function () { return require('./translations/ko.json.js'); });
case './translations/ml.json': return Promise.resolve().then(function () { return require('./translations/ml.json.js'); });
case './translations/ms.json': return Promise.resolve().then(function () { return require('./translations/ms.json.js'); });
case './translations/nl.json': return Promise.resolve().then(function () { return require('./translations/nl.json.js'); });
case './translations/no.json': return Promise.resolve().then(function () { return require('./translations/no.json.js'); });
case './translations/pl.json': return Promise.resolve().then(function () { return require('./translations/pl.json.js'); });
case './translations/pt-BR.json': return Promise.resolve().then(function () { return require('./translations/pt-BR.json.js'); });
case './translations/pt.json': return Promise.resolve().then(function () { return require('./translations/pt.json.js'); });
case './translations/ru.json': return Promise.resolve().then(function () { return require('./translations/ru.json.js'); });
case './translations/sa.json': return Promise.resolve().then(function () { return require('./translations/sa.json.js'); });
case './translations/sk.json': return Promise.resolve().then(function () { return require('./translations/sk.json.js'); });
case './translations/sv.json': return Promise.resolve().then(function () { return require('./translations/sv.json.js'); });
case './translations/th.json': return Promise.resolve().then(function () { return require('./translations/th.json.js'); });
case './translations/tr.json': return Promise.resolve().then(function () { return require('./translations/tr.json.js'); });
case './translations/uk.json': return Promise.resolve().then(function () { return require('./translations/uk.json.js'); });
case './translations/vi.json': return Promise.resolve().then(function () { return require('./translations/vi.json.js'); });
case './translations/zh-Hans.json': return Promise.resolve().then(function () { return require('./translations/zh-Hans.json.js'); });
case './translations/zh.json': return Promise.resolve().then(function () { return require('./translations/zh.json.js'); });
default: return new Promise(function(resolve, reject) {
(typeof queueMicrotask === 'function' ? queueMicrotask : setTimeout)(
reject.bind(null, new Error("Unknown variable dynamic import: " + path))
);
})
}
}
function __variableDynamicImportRuntime0__(path) {
switch (path) {
case './translations/en-GB.js': return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('./translations/en-GB.js')); });
default: return new Promise(function(resolve, reject) {
(typeof queueMicrotask === 'function' ? queueMicrotask : setTimeout)(
reject.bind(null, new Error("Unknown variable dynamic import: " + path))
);
})
}
}
const { INJECT_COLUMN_IN_TABLE, MUTATE_COLLECTION_TYPES_LINKS, MUTATE_EDIT_VIEW_LAYOUT, MUTATE_SINGLE_TYPES_LINKS } = constants.HOOKS;
class StrapiApp {
async bootstrap(customBootstrap) {
Object.keys(this.appPlugins).forEach((plugin)=>{
const bootstrap = this.appPlugins[plugin].bootstrap;
if (bootstrap) {
bootstrap({
addSettingsLink: this.addSettingsLink,
addSettingsLinks: this.addSettingsLinks,
getPlugin: this.getPlugin,
registerHook: this.registerHook
});
}
});
if (isFunction(customBootstrap)) {
customBootstrap({
addComponents: this.addComponents,
addFields: this.addFields,
addMenuLink: this.addMenuLink,
addReducers: this.addReducers,
addSettingsLink: this.addSettingsLink,
addSettingsLinks: this.addSettingsLinks,
getPlugin: this.getPlugin,
registerHook: this.registerHook
});
}
}
async register(customRegister) {
Object.keys(this.appPlugins).forEach((plugin)=>{
this.appPlugins[plugin].register(this);
});
if (isFunction(customRegister)) {
customRegister(this);
}
}
async loadAdminTrads() {
const adminLocales = await Promise.all(this.configurations.locales.map(async (locale)=>{
try {
const { default: data } = await __variableDynamicImportRuntime0__(`./translations/${locale}.js`);
return {
data,
locale
};
} catch {
try {
const { default: data } = await __variableDynamicImportRuntime1__(`./translations/${locale}.json`);
return {
data,
locale
};
} catch {
return {
data: null,
locale
};
}
}
}));
return adminLocales.reduce((acc, current)=>{
if (current.data) {
acc[current.locale] = current.data;
}
return acc;
}, {});
}
/**
* Load the application's translations and merged the custom translations
* with the default ones.
*/ async loadTrads(customTranslations = {}) {
const adminTranslations = await this.loadAdminTrads();
const arrayOfPromises = Object.keys(this.appPlugins).map((plugin)=>{
const registerTrads = this.appPlugins[plugin].registerTrads;
if (registerTrads) {
return registerTrads({
locales: this.configurations.locales
});
}
return null;
}).filter((a)=>a);
const pluginsTrads = await Promise.all(arrayOfPromises);
const mergedTrads = pluginsTrads.reduce((acc, currentPluginTrads)=>{
const pluginTrads = currentPluginTrads.reduce((acc1, current)=>{
acc1[current.locale] = current.data;
return acc1;
}, {});
Object.keys(pluginTrads).forEach((locale)=>{
acc[locale] = {
...acc[locale],
...pluginTrads[locale]
};
});
return acc;
}, {});
const translations = this.configurations.locales.reduce((acc, current)=>{
acc[current] = {
...adminTranslations[current],
...mergedTrads[current] || {},
...customTranslations[current] ?? {}
};
return acc;
}, {});
this.configurations.translations = translations;
return Promise.resolve();
}
render() {
const localeNames = pick(languageNativeNames.languageNativeNames, this.configurations.locales || []);
const locale = localStorage.getItem(reducer.LANGUAGE_LOCAL_STORAGE_KEY) || 'en';
this.store = configure.configureStore({
admin_app: {
permissions: merge({}, constants.ADMIN_PERMISSIONS_CE, constants$1.ADMIN_PERMISSIONS_EE),
theme: {
availableThemes: [],
currentTheme: localStorage.getItem(reducer.THEME_LOCAL_STORAGE_KEY) || 'system'
},
language: {
locale: localeNames[locale] ? locale : 'en',
localeNames
},
token: reducer.getStoredToken()
}
}, this.middlewares, this.reducers);
const router = this.router.createRouter(this, {
basename: basename.getBasename()
});
return /*#__PURE__*/ jsxRuntime.jsx(reactRouterDom.RouterProvider, {
router: router
});
}
constructor({ config, appPlugins } = {}){
this.plugins = {};
this.hooksDict = {};
this.admin = {
injectionZones: {}
};
this.translations = {};
this.configurations = {
authLogo: logoStrapi2022,
head: {
favicon: ''
},
locales: [
'en'
],
menuLogo: logoStrapi2022,
notifications: {
releases: true
},
themes: {
light: designSystem.lightTheme,
dark: designSystem.darkTheme
},
translations: {},
tutorials: true
};
/**
* APIs
*/ this.rbac = new rbac.RBAC();
this.library = {
components: {},
fields: {}
};
this.middlewares = [];
this.reducers = {};
this.store = null;
this.customFields = new CustomFields.CustomFields();
this.widgets = new Widgets.Widgets();
this.addComponents = (components)=>{
if (Array.isArray(components)) {
components.map((comp)=>{
invariant(comp.Component, 'A Component must be provided');
invariant(comp.name, 'A type must be provided');
this.library.components[comp.name] = comp.Component;
});
} else {
invariant(components.Component, 'A Component must be provided');
invariant(components.name, 'A type must be provided');
this.library.components[components.name] = components.Component;
}
};
this.addFields = (fields)=>{
if (Array.isArray(fields)) {
fields.map((field)=>{
invariant(field.Component, 'A Component must be provided');
invariant(field.type, 'A type must be provided');
this.library.fields[field.type] = field.Component;
});
} else {
invariant(fields.Component, 'A Component must be provided');
invariant(fields.type, 'A type must be provided');
this.library.fields[fields.type] = fields.Component;
}
};
this.addMiddlewares = (middlewares)=>{
middlewares.forEach((middleware)=>{
this.middlewares.push(middleware);
});
};
this.addRBACMiddleware = (m)=>{
if (Array.isArray(m)) {
this.rbac.use(m);
} else {
this.rbac.use(m);
}
};
this.addReducers = (reducers)=>{
/**
* TODO: when we upgrade to redux-toolkit@2 and we can also dynamically add middleware,
* we'll deprecate these two APIs in favour of their hook counterparts.
*/ Object.entries(reducers).forEach(([name, reducer])=>{
this.reducers[name] = reducer;
});
};
this.addMenuLink = (link)=>this.router.addMenuLink(link);
/**
* @deprecated use `addSettingsLink` instead, it internally supports
* adding multiple links at once.
*/ this.addSettingsLinks = (sectionId, links)=>{
invariant(Array.isArray(links), 'TypeError expected links to be an array');
this.router.addSettingsLink(sectionId, links);
};
/**
* @deprecated use `addSettingsLink` instead, you can pass a section object to
* create the section and links at the same time.
*/ this.createSettingSection = (section, links)=>this.router.addSettingsLink(section, links);
this.addSettingsLink = (sectionId, link)=>{
this.router.addSettingsLink(sectionId, link);
};
this.createCustomConfigurations = (customConfig)=>{
if (customConfig.locales) {
this.configurations.locales = [
'en',
...customConfig.locales?.filter((loc)=>loc !== 'en') || []
];
}
if (customConfig.auth?.logo) {
this.configurations.authLogo = customConfig.auth.logo;
}
if (customConfig.menu?.logo) {
this.configurations.menuLogo = customConfig.menu.logo;
}
if (customConfig.head?.favicon) {
this.configurations.head.favicon = customConfig.head.favicon;
}
if (customConfig.theme) {
const darkTheme = customConfig.theme.dark;
const lightTheme = customConfig.theme.light;
if (!darkTheme && !lightTheme) {
console.warn(`[deprecated] In future versions, Strapi will stop supporting this theme customization syntax. The theme configuration accepts a light and a dark key to customize each theme separately. See https://docs.strapi.io/developer-docs/latest/development/admin-customization.html#theme-extension.`.trim());
merge(this.configurations.themes.light, customConfig.theme);
}
if (lightTheme) merge(this.configurations.themes.light, lightTheme);
if (darkTheme) merge(this.configurations.themes.dark, darkTheme);
}
if (customConfig.notifications?.releases !== undefined) {
this.configurations.notifications.releases = customConfig.notifications.releases;
}
if (customConfig.tutorials !== undefined) {
this.configurations.tutorials = customConfig.tutorials;
}
};
this.createHook = (name)=>{
this.hooksDict[name] = createHook.createHook();
};
this.getAdminInjectedComponents = (moduleName, containerName, blockName)=>{
try {
// @ts-expect-error – we have a catch block so if you don't pass it correctly we still return an array.
return this.admin.injectionZones[moduleName][containerName][blockName] || [];
} catch (err) {
console.error('Cannot get injected component', err);
return [];
}
};
this.getPlugin = (pluginId)=>this.plugins[pluginId];
this.registerHook = (name, fn)=>{
invariant(this.hooksDict[name], `The hook ${name} is not defined. You are trying to register a hook that does not exist in the application.`);
this.hooksDict[name].register(fn);
};
this.registerPlugin = (pluginConf)=>{
const plugin = new Plugin.Plugin(pluginConf);
this.plugins[plugin.pluginId] = plugin;
};
this.runHookSeries = (name, asynchronous = false)=>asynchronous ? this.hooksDict[name].runSeriesAsync() : this.hooksDict[name].runSeries();
this.runHookWaterfall = (name, initialValue, store)=>{
return this.hooksDict[name].runWaterfall(initialValue, store);
};
this.runHookParallel = (name)=>this.hooksDict[name].runParallel();
this.appPlugins = appPlugins || {};
this.createCustomConfigurations(config ?? {});
this.createHook(INJECT_COLUMN_IN_TABLE);
this.createHook(MUTATE_COLLECTION_TYPES_LINKS);
this.createHook(MUTATE_SINGLE_TYPES_LINKS);
this.createHook(MUTATE_EDIT_VIEW_LAYOUT);
this.router = new router.Router(router$1.getInitialRoutes());
}
}
exports.StrapiApp = StrapiApp;
//# sourceMappingURL=StrapiApp.js.map
@@ -0,0 +1 @@
{"version":3,"file":"StrapiApp.js","sources":["../../../../admin/src/StrapiApp.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { darkTheme, lightTheme } from '@strapi/design-system';\nimport invariant from 'invariant';\nimport isFunction from 'lodash/isFunction';\nimport merge from 'lodash/merge';\nimport pick from 'lodash/pick';\nimport { RouterProvider } from 'react-router-dom';\nimport { DefaultTheme } from 'styled-components';\n\nimport { ADMIN_PERMISSIONS_EE } from '../../ee/admin/src/constants';\n\nimport Logo from './assets/images/logo-strapi-2022.svg';\nimport { ADMIN_PERMISSIONS_CE, HOOKS } from './constants';\nimport { CustomFields } from './core/apis/CustomFields';\nimport { Plugin, PluginConfig } from './core/apis/Plugin';\nimport { RBAC, RBACMiddleware } from './core/apis/rbac';\nimport { Router, StrapiAppSetting, UnloadedSettingsLink } from './core/apis/router';\nimport { Widgets } from './core/apis/Widgets';\nimport { RootState, Store, configureStore } from './core/store/configure';\nimport { getBasename } from './core/utils/basename';\nimport { Handler, createHook } from './core/utils/createHook';\nimport {\n THEME_LOCAL_STORAGE_KEY,\n LANGUAGE_LOCAL_STORAGE_KEY,\n ThemeName,\n getStoredToken,\n} from './reducer';\nimport { getInitialRoutes } from './router';\nimport { languageNativeNames } from './translations/languageNativeNames';\n\nimport type { ReducersMapObject, Middleware } from '@reduxjs/toolkit';\n\nconst {\n INJECT_COLUMN_IN_TABLE,\n MUTATE_COLLECTION_TYPES_LINKS,\n MUTATE_EDIT_VIEW_LAYOUT,\n MUTATE_SINGLE_TYPES_LINKS,\n} = HOOKS;\n\ninterface StrapiAppConstructorArgs extends Partial<Pick<StrapiApp, 'appPlugins'>> {\n config?: {\n auth?: { logo: string };\n head?: { favicon: string };\n locales?: string[];\n menu?: { logo: string };\n notifications?: { releases: boolean };\n theme?: { light: DefaultTheme; dark: DefaultTheme };\n translations?: Record<string, Record<string, string>>;\n tutorials?: boolean;\n };\n}\n\ntype Translation = { data: Record<string, string>; locale: string };\ntype Translations = Array<Translation>;\n\ninterface StrapiAppPlugin {\n bootstrap?: (\n args: Pick<StrapiApp, 'addSettingsLink' | 'addSettingsLinks' | 'getPlugin' | 'registerHook'>\n ) => void;\n register: (app: StrapiApp) => void;\n registerTrads?: (args: { locales: string[] }) => Promise<Translations>;\n}\n\ninterface InjectionZoneComponent {\n Component: React.ComponentType;\n name: string;\n // TODO: in theory this could receive and forward any React component prop\n // but in practice there only seems to be once instance, where `slug` is\n // forwarded. The type needs to become either more generic or we disallow\n // prop spreading and offer a different way to access context data.\n slug: string;\n}\n\ninterface Component {\n name: string;\n Component: React.ComponentType;\n}\n\ninterface Field {\n type: string;\n Component: React.ComponentType;\n}\n\ninterface Library {\n fields: Record<Field['type'], Field['Component']>;\n components: Record<Component['name'], Component['Component']>;\n}\n\nclass StrapiApp {\n appPlugins: Record<string, StrapiAppPlugin>;\n plugins: Record<string, Plugin> = {};\n hooksDict: Record<string, ReturnType<typeof createHook>> = {};\n\n admin = {\n injectionZones: {},\n };\n\n translations: StrapiApp['configurations']['translations'] = {};\n\n configurations = {\n authLogo: Logo,\n head: { favicon: '' },\n locales: ['en'],\n menuLogo: Logo,\n notifications: { releases: true },\n themes: { light: lightTheme, dark: darkTheme },\n translations: {},\n tutorials: true,\n };\n\n /**\n * APIs\n */\n rbac = new RBAC();\n router: Router;\n library: Library = {\n components: {},\n fields: {},\n };\n middlewares: Array<() => Middleware<object, RootState>> = [];\n reducers: ReducersMapObject = {};\n store: Store | null = null;\n customFields = new CustomFields();\n widgets = new Widgets();\n\n constructor({ config, appPlugins }: StrapiAppConstructorArgs = {}) {\n this.appPlugins = appPlugins || {};\n\n this.createCustomConfigurations(config ?? {});\n\n this.createHook(INJECT_COLUMN_IN_TABLE);\n this.createHook(MUTATE_COLLECTION_TYPES_LINKS);\n this.createHook(MUTATE_SINGLE_TYPES_LINKS);\n this.createHook(MUTATE_EDIT_VIEW_LAYOUT);\n\n this.router = new Router(getInitialRoutes());\n }\n\n addComponents = (components: Component | Component[]) => {\n if (Array.isArray(components)) {\n components.map((comp) => {\n invariant(comp.Component, 'A Component must be provided');\n invariant(comp.name, 'A type must be provided');\n\n this.library.components[comp.name] = comp.Component;\n });\n } else {\n invariant(components.Component, 'A Component must be provided');\n invariant(components.name, 'A type must be provided');\n\n this.library.components[components.name] = components.Component;\Line truncated
+375
View File
@@ -0,0 +1,375 @@
import { jsx } from 'react/jsx-runtime';
import 'react';
import { lightTheme, darkTheme } from '@strapi/design-system';
import invariant from 'invariant';
import isFunction from 'lodash/isFunction';
import merge from 'lodash/merge';
import pick from 'lodash/pick';
import { RouterProvider } from 'react-router-dom';
import { ADMIN_PERMISSIONS_EE } from '../../ee/admin/src/constants.mjs';
import img from './assets/images/logo-strapi-2022.svg.mjs';
import { ADMIN_PERMISSIONS_CE, HOOKS } from './constants.mjs';
import { CustomFields } from './core/apis/CustomFields.mjs';
import { Plugin } from './core/apis/Plugin.mjs';
import { RBAC } from './core/apis/rbac.mjs';
import { Router } from './core/apis/router.mjs';
import { Widgets } from './core/apis/Widgets.mjs';
import { configureStore as configureStoreImpl } from './core/store/configure.mjs';
import { getBasename } from './core/utils/basename.mjs';
import { createHook } from './core/utils/createHook.mjs';
import { LANGUAGE_LOCAL_STORAGE_KEY, THEME_LOCAL_STORAGE_KEY, getStoredToken } from './reducer.mjs';
import { getInitialRoutes } from './router.mjs';
import { languageNativeNames } from './translations/languageNativeNames.mjs';
function __variableDynamicImportRuntime1__(path) {
switch (path) {
case './translations/ar.json': return import('./translations/ar.json.mjs');
case './translations/ca.json': return import('./translations/ca.json.mjs');
case './translations/cs.json': return import('./translations/cs.json.mjs');
case './translations/de.json': return import('./translations/de.json.mjs');
case './translations/dk.json': return import('./translations/dk.json.mjs');
case './translations/en.json': return import('./translations/en.json.mjs');
case './translations/es.json': return import('./translations/es.json.mjs');
case './translations/eu.json': return import('./translations/eu.json.mjs');
case './translations/fr.json': return import('./translations/fr.json.mjs');
case './translations/gu.json': return import('./translations/gu.json.mjs');
case './translations/he.json': return import('./translations/he.json.mjs');
case './translations/hi.json': return import('./translations/hi.json.mjs');
case './translations/hu.json': return import('./translations/hu.json.mjs');
case './translations/id.json': return import('./translations/id.json.mjs');
case './translations/it.json': return import('./translations/it.json.mjs');
case './translations/ja.json': return import('./translations/ja.json.mjs');
case './translations/ko.json': return import('./translations/ko.json.mjs');
case './translations/ml.json': return import('./translations/ml.json.mjs');
case './translations/ms.json': return import('./translations/ms.json.mjs');
case './translations/nl.json': return import('./translations/nl.json.mjs');
case './translations/no.json': return import('./translations/no.json.mjs');
case './translations/pl.json': return import('./translations/pl.json.mjs');
case './translations/pt-BR.json': return import('./translations/pt-BR.json.mjs');
case './translations/pt.json': return import('./translations/pt.json.mjs');
case './translations/ru.json': return import('./translations/ru.json.mjs');
case './translations/sa.json': return import('./translations/sa.json.mjs');
case './translations/sk.json': return import('./translations/sk.json.mjs');
case './translations/sv.json': return import('./translations/sv.json.mjs');
case './translations/th.json': return import('./translations/th.json.mjs');
case './translations/tr.json': return import('./translations/tr.json.mjs');
case './translations/uk.json': return import('./translations/uk.json.mjs');
case './translations/vi.json': return import('./translations/vi.json.mjs');
case './translations/zh-Hans.json': return import('./translations/zh-Hans.json.mjs');
case './translations/zh.json': return import('./translations/zh.json.mjs');
default: return new Promise(function(resolve, reject) {
(typeof queueMicrotask === 'function' ? queueMicrotask : setTimeout)(
reject.bind(null, new Error("Unknown variable dynamic import: " + path))
);
})
}
}
function __variableDynamicImportRuntime0__(path) {
switch (path) {
case './translations/en-GB.js': return import('./translations/en-GB.mjs');
default: return new Promise(function(resolve, reject) {
(typeof queueMicrotask === 'function' ? queueMicrotask : setTimeout)(
reject.bind(null, new Error("Unknown variable dynamic import: " + path))
);
})
}
}
const { INJECT_COLUMN_IN_TABLE, MUTATE_COLLECTION_TYPES_LINKS, MUTATE_EDIT_VIEW_LAYOUT, MUTATE_SINGLE_TYPES_LINKS } = HOOKS;
class StrapiApp {
async bootstrap(customBootstrap) {
Object.keys(this.appPlugins).forEach((plugin)=>{
const bootstrap = this.appPlugins[plugin].bootstrap;
if (bootstrap) {
bootstrap({
addSettingsLink: this.addSettingsLink,
addSettingsLinks: this.addSettingsLinks,
getPlugin: this.getPlugin,
registerHook: this.registerHook
});
}
});
if (isFunction(customBootstrap)) {
customBootstrap({
addComponents: this.addComponents,
addFields: this.addFields,
addMenuLink: this.addMenuLink,
addReducers: this.addReducers,
addSettingsLink: this.addSettingsLink,
addSettingsLinks: this.addSettingsLinks,
getPlugin: this.getPlugin,
registerHook: this.registerHook
});
}
}
async register(customRegister) {
Object.keys(this.appPlugins).forEach((plugin)=>{
this.appPlugins[plugin].register(this);
});
if (isFunction(customRegister)) {
customRegister(this);
}
}
async loadAdminTrads() {
const adminLocales = await Promise.all(this.configurations.locales.map(async (locale)=>{
try {
const { default: data } = await __variableDynamicImportRuntime0__(`./translations/${locale}.js`);
return {
data,
locale
};
} catch {
try {
const { default: data } = await __variableDynamicImportRuntime1__(`./translations/${locale}.json`);
return {
data,
locale
};
} catch {
return {
data: null,
locale
};
}
}
}));
return adminLocales.reduce((acc, current)=>{
if (current.data) {
acc[current.locale] = current.data;
}
return acc;
}, {});
}
/**
* Load the application's translations and merged the custom translations
* with the default ones.
*/ async loadTrads(customTranslations = {}) {
const adminTranslations = await this.loadAdminTrads();
const arrayOfPromises = Object.keys(this.appPlugins).map((plugin)=>{
const registerTrads = this.appPlugins[plugin].registerTrads;
if (registerTrads) {
return registerTrads({
locales: this.configurations.locales
});
}
return null;
}).filter((a)=>a);
const pluginsTrads = await Promise.all(arrayOfPromises);
const mergedTrads = pluginsTrads.reduce((acc, currentPluginTrads)=>{
const pluginTrads = currentPluginTrads.reduce((acc1, current)=>{
acc1[current.locale] = current.data;
return acc1;
}, {});
Object.keys(pluginTrads).forEach((locale)=>{
acc[locale] = {
...acc[locale],
...pluginTrads[locale]
};
});
return acc;
}, {});
const translations = this.configurations.locales.reduce((acc, current)=>{
acc[current] = {
...adminTranslations[current],
...mergedTrads[current] || {},
...customTranslations[current] ?? {}
};
return acc;
}, {});
this.configurations.translations = translations;
return Promise.resolve();
}
render() {
const localeNames = pick(languageNativeNames, this.configurations.locales || []);
const locale = localStorage.getItem(LANGUAGE_LOCAL_STORAGE_KEY) || 'en';
this.store = configureStoreImpl({
admin_app: {
permissions: merge({}, ADMIN_PERMISSIONS_CE, ADMIN_PERMISSIONS_EE),
theme: {
availableThemes: [],
currentTheme: localStorage.getItem(THEME_LOCAL_STORAGE_KEY) || 'system'
},
language: {
locale: localeNames[locale] ? locale : 'en',
localeNames
},
token: getStoredToken()
}
}, this.middlewares, this.reducers);
const router = this.router.createRouter(this, {
basename: getBasename()
});
return /*#__PURE__*/ jsx(RouterProvider, {
router: router
});
}
constructor({ config, appPlugins } = {}){
this.plugins = {};
this.hooksDict = {};
this.admin = {
injectionZones: {}
};
this.translations = {};
this.configurations = {
authLogo: img,
head: {
favicon: ''
},
locales: [
'en'
],
menuLogo: img,
notifications: {
releases: true
},
themes: {
light: lightTheme,
dark: darkTheme
},
translations: {},
tutorials: true
};
/**
* APIs
*/ this.rbac = new RBAC();
this.library = {
components: {},
fields: {}
};
this.middlewares = [];
this.reducers = {};
this.store = null;
this.customFields = new CustomFields();
this.widgets = new Widgets();
this.addComponents = (components)=>{
if (Array.isArray(components)) {
components.map((comp)=>{
invariant(comp.Component, 'A Component must be provided');
invariant(comp.name, 'A type must be provided');
this.library.components[comp.name] = comp.Component;
});
} else {
invariant(components.Component, 'A Component must be provided');
invariant(components.name, 'A type must be provided');
this.library.components[components.name] = components.Component;
}
};
this.addFields = (fields)=>{
if (Array.isArray(fields)) {
fields.map((field)=>{
invariant(field.Component, 'A Component must be provided');
invariant(field.type, 'A type must be provided');
this.library.fields[field.type] = field.Component;
});
} else {
invariant(fields.Component, 'A Component must be provided');
invariant(fields.type, 'A type must be provided');
this.library.fields[fields.type] = fields.Component;
}
};
this.addMiddlewares = (middlewares)=>{
middlewares.forEach((middleware)=>{
this.middlewares.push(middleware);
});
};
this.addRBACMiddleware = (m)=>{
if (Array.isArray(m)) {
this.rbac.use(m);
} else {
this.rbac.use(m);
}
};
this.addReducers = (reducers)=>{
/**
* TODO: when we upgrade to redux-toolkit@2 and we can also dynamically add middleware,
* we'll deprecate these two APIs in favour of their hook counterparts.
*/ Object.entries(reducers).forEach(([name, reducer])=>{
this.reducers[name] = reducer;
});
};
this.addMenuLink = (link)=>this.router.addMenuLink(link);
/**
* @deprecated use `addSettingsLink` instead, it internally supports
* adding multiple links at once.
*/ this.addSettingsLinks = (sectionId, links)=>{
invariant(Array.isArray(links), 'TypeError expected links to be an array');
this.router.addSettingsLink(sectionId, links);
};
/**
* @deprecated use `addSettingsLink` instead, you can pass a section object to
* create the section and links at the same time.
*/ this.createSettingSection = (section, links)=>this.router.addSettingsLink(section, links);
this.addSettingsLink = (sectionId, link)=>{
this.router.addSettingsLink(sectionId, link);
};
this.createCustomConfigurations = (customConfig)=>{
if (customConfig.locales) {
this.configurations.locales = [
'en',
...customConfig.locales?.filter((loc)=>loc !== 'en') || []
];
}
if (customConfig.auth?.logo) {
this.configurations.authLogo = customConfig.auth.logo;
}
if (customConfig.menu?.logo) {
this.configurations.menuLogo = customConfig.menu.logo;
}
if (customConfig.head?.favicon) {
this.configurations.head.favicon = customConfig.head.favicon;
}
if (customConfig.theme) {
const darkTheme = customConfig.theme.dark;
const lightTheme = customConfig.theme.light;
if (!darkTheme && !lightTheme) {
console.warn(`[deprecated] In future versions, Strapi will stop supporting this theme customization syntax. The theme configuration accepts a light and a dark key to customize each theme separately. See https://docs.strapi.io/developer-docs/latest/development/admin-customization.html#theme-extension.`.trim());
merge(this.configurations.themes.light, customConfig.theme);
}
if (lightTheme) merge(this.configurations.themes.light, lightTheme);
if (darkTheme) merge(this.configurations.themes.dark, darkTheme);
}
if (customConfig.notifications?.releases !== undefined) {
this.configurations.notifications.releases = customConfig.notifications.releases;
}
if (customConfig.tutorials !== undefined) {
this.configurations.tutorials = customConfig.tutorials;
}
};
this.createHook = (name)=>{
this.hooksDict[name] = createHook();
};
this.getAdminInjectedComponents = (moduleName, containerName, blockName)=>{
try {
// @ts-expect-error – we have a catch block so if you don't pass it correctly we still return an array.
return this.admin.injectionZones[moduleName][containerName][blockName] || [];
} catch (err) {
console.error('Cannot get injected component', err);
return [];
}
};
this.getPlugin = (pluginId)=>this.plugins[pluginId];
this.registerHook = (name, fn)=>{
invariant(this.hooksDict[name], `The hook ${name} is not defined. You are trying to register a hook that does not exist in the application.`);
this.hooksDict[name].register(fn);
};
this.registerPlugin = (pluginConf)=>{
const plugin = new Plugin(pluginConf);
this.plugins[plugin.pluginId] = plugin;
};
this.runHookSeries = (name, asynchronous = false)=>asynchronous ? this.hooksDict[name].runSeriesAsync() : this.hooksDict[name].runSeries();
this.runHookWaterfall = (name, initialValue, store)=>{
return this.hooksDict[name].runWaterfall(initialValue, store);
};
this.runHookParallel = (name)=>this.hooksDict[name].runParallel();
this.appPlugins = appPlugins || {};
this.createCustomConfigurations(config ?? {});
this.createHook(INJECT_COLUMN_IN_TABLE);
this.createHook(MUTATE_COLLECTION_TYPES_LINKS);
this.createHook(MUTATE_SINGLE_TYPES_LINKS);
this.createHook(MUTATE_EDIT_VIEW_LAYOUT);
this.router = new Router(getInitialRoutes());
}
}
export { StrapiApp };
//# sourceMappingURL=StrapiApp.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"StrapiApp.mjs","sources":["../../../../admin/src/StrapiApp.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { darkTheme, lightTheme } from '@strapi/design-system';\nimport invariant from 'invariant';\nimport isFunction from 'lodash/isFunction';\nimport merge from 'lodash/merge';\nimport pick from 'lodash/pick';\nimport { RouterProvider } from 'react-router-dom';\nimport { DefaultTheme } from 'styled-components';\n\nimport { ADMIN_PERMISSIONS_EE } from '../../ee/admin/src/constants';\n\nimport Logo from './assets/images/logo-strapi-2022.svg';\nimport { ADMIN_PERMISSIONS_CE, HOOKS } from './constants';\nimport { CustomFields } from './core/apis/CustomFields';\nimport { Plugin, PluginConfig } from './core/apis/Plugin';\nimport { RBAC, RBACMiddleware } from './core/apis/rbac';\nimport { Router, StrapiAppSetting, UnloadedSettingsLink } from './core/apis/router';\nimport { Widgets } from './core/apis/Widgets';\nimport { RootState, Store, configureStore } from './core/store/configure';\nimport { getBasename } from './core/utils/basename';\nimport { Handler, createHook } from './core/utils/createHook';\nimport {\n THEME_LOCAL_STORAGE_KEY,\n LANGUAGE_LOCAL_STORAGE_KEY,\n ThemeName,\n getStoredToken,\n} from './reducer';\nimport { getInitialRoutes } from './router';\nimport { languageNativeNames } from './translations/languageNativeNames';\n\nimport type { ReducersMapObject, Middleware } from '@reduxjs/toolkit';\n\nconst {\n INJECT_COLUMN_IN_TABLE,\n MUTATE_COLLECTION_TYPES_LINKS,\n MUTATE_EDIT_VIEW_LAYOUT,\n MUTATE_SINGLE_TYPES_LINKS,\n} = HOOKS;\n\ninterface StrapiAppConstructorArgs extends Partial<Pick<StrapiApp, 'appPlugins'>> {\n config?: {\n auth?: { logo: string };\n head?: { favicon: string };\n locales?: string[];\n menu?: { logo: string };\n notifications?: { releases: boolean };\n theme?: { light: DefaultTheme; dark: DefaultTheme };\n translations?: Record<string, Record<string, string>>;\n tutorials?: boolean;\n };\n}\n\ntype Translation = { data: Record<string, string>; locale: string };\ntype Translations = Array<Translation>;\n\ninterface StrapiAppPlugin {\n bootstrap?: (\n args: Pick<StrapiApp, 'addSettingsLink' | 'addSettingsLinks' | 'getPlugin' | 'registerHook'>\n ) => void;\n register: (app: StrapiApp) => void;\n registerTrads?: (args: { locales: string[] }) => Promise<Translations>;\n}\n\ninterface InjectionZoneComponent {\n Component: React.ComponentType;\n name: string;\n // TODO: in theory this could receive and forward any React component prop\n // but in practice there only seems to be once instance, where `slug` is\n // forwarded. The type needs to become either more generic or we disallow\n // prop spreading and offer a different way to access context data.\n slug: string;\n}\n\ninterface Component {\n name: string;\n Component: React.ComponentType;\n}\n\ninterface Field {\n type: string;\n Component: React.ComponentType;\n}\n\ninterface Library {\n fields: Record<Field['type'], Field['Component']>;\n components: Record<Component['name'], Component['Component']>;\n}\n\nclass StrapiApp {\n appPlugins: Record<string, StrapiAppPlugin>;\n plugins: Record<string, Plugin> = {};\n hooksDict: Record<string, ReturnType<typeof createHook>> = {};\n\n admin = {\n injectionZones: {},\n };\n\n translations: StrapiApp['configurations']['translations'] = {};\n\n configurations = {\n authLogo: Logo,\n head: { favicon: '' },\n locales: ['en'],\n menuLogo: Logo,\n notifications: { releases: true },\n themes: { light: lightTheme, dark: darkTheme },\n translations: {},\n tutorials: true,\n };\n\n /**\n * APIs\n */\n rbac = new RBAC();\n router: Router;\n library: Library = {\n components: {},\n fields: {},\n };\n middlewares: Array<() => Middleware<object, RootState>> = [];\n reducers: ReducersMapObject = {};\n store: Store | null = null;\n customFields = new CustomFields();\n widgets = new Widgets();\n\n constructor({ config, appPlugins }: StrapiAppConstructorArgs = {}) {\n this.appPlugins = appPlugins || {};\n\n this.createCustomConfigurations(config ?? {});\n\n this.createHook(INJECT_COLUMN_IN_TABLE);\n this.createHook(MUTATE_COLLECTION_TYPES_LINKS);\n this.createHook(MUTATE_SINGLE_TYPES_LINKS);\n this.createHook(MUTATE_EDIT_VIEW_LAYOUT);\n\n this.router = new Router(getInitialRoutes());\n }\n\n addComponents = (components: Component | Component[]) => {\n if (Array.isArray(components)) {\n components.map((comp) => {\n invariant(comp.Component, 'A Component must be provided');\n invariant(comp.name, 'A type must be provided');\n\n this.library.components[comp.name] = comp.Component;\n });\n } else {\n invariant(components.Component, 'A Component must be provided');\n invariant(components.name, 'A type must be provided');\n\n this.library.components[components.name] = components.Component;Line truncated
@@ -0,0 +1,6 @@
'use strict';
var img = "data:image/svg+xml,%3csvg width='800' height='800' viewBox='0 0 800 800' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3cpath d='M39 282c0-118 0-176.9 36.6-213.5C112.2 32 171.1 32 288.9 32h221.2c117.8 0 176.7 0 213.3 36.6C760 105.2 760 164.1 760 281.9v221.2c0 117.8 0 176.7-36.6 213.3C686.8 753 627.9 753 510.1 753H288.9c-117.8 0-176.7 0-213.3-36.6C39 679.8 39 620.9 39 503.1V281.9Z' fill='%234945FF'/%3e %3cpath fill-rule='evenodd' clip-rule='evenodd' d='M536.4 250.7H293.7v123.8h123.8v123.7h123.8V255.5c0-2.6-2.2-4.8-4.9-4.8Z' fill='white'/%3e %3cpath fill='white' d='M412.7 374.5h4.8v4.8h-4.8z'/%3e %3cpath d='M293.8 374.5h119c2.6 0 4.8 2.1 4.8 4.8v119h-119a4.8 4.8 0 0 1-4.8-4.9v-119Z' fill='%239593FF'/%3e %3cpath d='M417.5 498.2h123.8L421.6 618a2.4 2.4 0 0 1-4-1.7v-118ZM293.8 374.5h-118a2.4 2.4 0 0 1-1.7-4.1l119.7-119.7v123.8Z' fill='%239593FF'/%3e%3c/svg%3e";
module.exports = img;
//# sourceMappingURL=logo-strapi-2022.svg.js.map
@@ -0,0 +1 @@
{"version":3,"file":"logo-strapi-2022.svg.js","sources":["../../../../../../admin/src/assets/images/logo-strapi-2022.svg"],"sourcesContent":["var img = \"data:image/svg+xml,%3csvg width='800' height='800' viewBox='0 0 800 800' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3cpath d='M39 282c0-118 0-176.9 36.6-213.5C112.2 32 171.1 32 288.9 32h221.2c117.8 0 176.7 0 213.3 36.6C760 105.2 760 164.1 760 281.9v221.2c0 117.8 0 176.7-36.6 213.3C686.8 753 627.9 753 510.1 753H288.9c-117.8 0-176.7 0-213.3-36.6C39 679.8 39 620.9 39 503.1V281.9Z' fill='%234945FF'/%3e %3cpath fill-rule='evenodd' clip-rule='evenodd' d='M536.4 250.7H293.7v123.8h123.8v123.7h123.8V255.5c0-2.6-2.2-4.8-4.9-4.8Z' fill='white'/%3e %3cpath fill='white' d='M412.7 374.5h4.8v4.8h-4.8z'/%3e %3cpath d='M293.8 374.5h119c2.6 0 4.8 2.1 4.8 4.8v119h-119a4.8 4.8 0 0 1-4.8-4.9v-119Z' fill='%239593FF'/%3e %3cpath d='M417.5 498.2h123.8L421.6 618a2.4 2.4 0 0 1-4-1.7v-118ZM293.8 374.5h-118a2.4 2.4 0 0 1-1.7-4.1l119.7-119.7v123.8Z' fill='%239593FF'/%3e%3c/svg%3e\";\n export default img;"],"names":["img"],"mappings":";;AAAA,IAAIA,GAAM,GAAA;;;;"}
@@ -0,0 +1,4 @@
var img = "data:image/svg+xml,%3csvg width='800' height='800' viewBox='0 0 800 800' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3cpath d='M39 282c0-118 0-176.9 36.6-213.5C112.2 32 171.1 32 288.9 32h221.2c117.8 0 176.7 0 213.3 36.6C760 105.2 760 164.1 760 281.9v221.2c0 117.8 0 176.7-36.6 213.3C686.8 753 627.9 753 510.1 753H288.9c-117.8 0-176.7 0-213.3-36.6C39 679.8 39 620.9 39 503.1V281.9Z' fill='%234945FF'/%3e %3cpath fill-rule='evenodd' clip-rule='evenodd' d='M536.4 250.7H293.7v123.8h123.8v123.7h123.8V255.5c0-2.6-2.2-4.8-4.9-4.8Z' fill='white'/%3e %3cpath fill='white' d='M412.7 374.5h4.8v4.8h-4.8z'/%3e %3cpath d='M293.8 374.5h119c2.6 0 4.8 2.1 4.8 4.8v119h-119a4.8 4.8 0 0 1-4.8-4.9v-119Z' fill='%239593FF'/%3e %3cpath d='M417.5 498.2h123.8L421.6 618a2.4 2.4 0 0 1-4-1.7v-118ZM293.8 374.5h-118a2.4 2.4 0 0 1-1.7-4.1l119.7-119.7v123.8Z' fill='%239593FF'/%3e%3c/svg%3e";
export { img as default };
//# sourceMappingURL=logo-strapi-2022.svg.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"logo-strapi-2022.svg.mjs","sources":["../../../../../../admin/src/assets/images/logo-strapi-2022.svg"],"sourcesContent":["var img = \"data:image/svg+xml,%3csvg width='800' height='800' viewBox='0 0 800 800' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3cpath d='M39 282c0-118 0-176.9 36.6-213.5C112.2 32 171.1 32 288.9 32h221.2c117.8 0 176.7 0 213.3 36.6C760 105.2 760 164.1 760 281.9v221.2c0 117.8 0 176.7-36.6 213.3C686.8 753 627.9 753 510.1 753H288.9c-117.8 0-176.7 0-213.3-36.6C39 679.8 39 620.9 39 503.1V281.9Z' fill='%234945FF'/%3e %3cpath fill-rule='evenodd' clip-rule='evenodd' d='M536.4 250.7H293.7v123.8h123.8v123.7h123.8V255.5c0-2.6-2.2-4.8-4.9-4.8Z' fill='white'/%3e %3cpath fill='white' d='M412.7 374.5h4.8v4.8h-4.8z'/%3e %3cpath d='M293.8 374.5h119c2.6 0 4.8 2.1 4.8 4.8v119h-119a4.8 4.8 0 0 1-4.8-4.9v-119Z' fill='%239593FF'/%3e %3cpath d='M417.5 498.2h123.8L421.6 618a2.4 2.4 0 0 1-4-1.7v-118ZM293.8 374.5h-118a2.4 2.4 0 0 1-1.7-4.1l119.7-119.7v123.8Z' fill='%239593FF'/%3e%3c/svg%3e\";\n export default img;"],"names":["img"],"mappings":"AAAA,IAAIA,GAAM,GAAA;;;;"}
@@ -0,0 +1,135 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var reactIntl = require('react-intl');
var styledComponents = require('styled-components');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
/**
* @beta
* @public
* @description A simple confirm dialog that out of the box can be used to confirm an action.
* The component can additionally be customised if required e.g. the footer actions can be
* completely replaced, but cannot be removed. Passing a string as the children prop will render
* the string as the body of the dialog. If you need more control over the body, you can pass a
* custom component as the children prop.
* @example
* ```tsx
* import { Dialog } from '@strapi/design-system';
*
* const DeleteAction = ({ id }) => {
* const [isOpen, setIsOpen] = React.useState(false);
*
* const [delete] = useDeleteMutation()
* const handleConfirm = async () => {
* await delete(id)
* setIsOpen(false)
* }
*
* return (
* <Dialog.Root open={isOpen} onOpenChange={setIsOpen}>
* <Dialog.Trigger>
* <Button>Delete</Button>
* </Dialog.Trigger>
* <ConfirmDialog onConfirm={handleConfirm} />
* </Dialog.Root>
* )
* }
* ```
*/ const ConfirmDialog = ({ children, icon = /*#__PURE__*/ jsxRuntime.jsx(StyledWarning, {}), onConfirm, onCancel, variant = 'danger-light', startAction, endAction, title })=>{
const { formatMessage } = reactIntl.useIntl();
const [isConfirming, setIsConfirming] = React__namespace.useState(false);
const content = children || formatMessage({
id: 'app.confirm.body',
defaultMessage: 'Are you sure?'
});
const handleConfirm = async (e)=>{
if (!onConfirm) {
return;
}
try {
setIsConfirming(true);
await onConfirm(e);
} finally{
setIsConfirming(false);
}
};
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Dialog.Content, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Header, {
children: title || formatMessage({
id: 'app.components.ConfirmDialog.title',
defaultMessage: 'Confirmation'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Body, {
icon: icon,
children: content
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Dialog.Footer, {
children: [
startAction || /*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Cancel, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
fullWidth: true,
variant: "tertiary",
onClick: (e)=>{
e.stopPropagation();
if (onCancel) {
onCancel(e);
}
},
children: formatMessage({
id: 'app.components.Button.cancel',
defaultMessage: 'Cancel'
})
})
}),
endAction || /*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Action, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
fullWidth: true,
onClick: handleConfirm,
variant: variant,
loading: isConfirming,
children: formatMessage({
id: 'app.components.Button.confirm',
defaultMessage: 'Confirm'
})
})
})
]
})
]
});
};
const StyledWarning = styledComponents.styled(icons.WarningCircle)`
width: 24px;
height: 24px;
path {
fill: ${({ theme })=>theme.colors.danger600};
}
`;
exports.ConfirmDialog = ConfirmDialog;
//# sourceMappingURL=ConfirmDialog.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ConfirmDialog.js","sources":["../../../../../admin/src/components/ConfirmDialog.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Button, ButtonProps, Dialog } from '@strapi/design-system';\nimport { WarningCircle } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\n/* -------------------------------------------------------------------------------------------------\n * ConfirmDialog\n * -----------------------------------------------------------------------------------------------*/\ninterface ConfirmDialogProps extends Pick<ButtonProps, 'variant'>, Pick<Dialog.BodyProps, 'icon'> {\n onConfirm?: (e?: React.MouseEvent<HTMLButtonElement>) => Promise<void> | void;\n onCancel?: (e?: React.MouseEvent<HTMLButtonElement>) => Promise<void> | void;\n children?: React.ReactNode;\n endAction?: React.ReactNode;\n startAction?: React.ReactNode;\n title?: React.ReactNode;\n}\n\n/**\n * @beta\n * @public\n * @description A simple confirm dialog that out of the box can be used to confirm an action.\n * The component can additionally be customised if required e.g. the footer actions can be\n * completely replaced, but cannot be removed. Passing a string as the children prop will render\n * the string as the body of the dialog. If you need more control over the body, you can pass a\n * custom component as the children prop.\n * @example\n * ```tsx\n * import { Dialog } from '@strapi/design-system';\n *\n * const DeleteAction = ({ id }) => {\n * const [isOpen, setIsOpen] = React.useState(false);\n *\n * const [delete] = useDeleteMutation()\n * const handleConfirm = async () => {\n * await delete(id)\n * setIsOpen(false)\n * }\n *\n * return (\n * <Dialog.Root open={isOpen} onOpenChange={setIsOpen}>\n * <Dialog.Trigger>\n * <Button>Delete</Button>\n * </Dialog.Trigger>\n * <ConfirmDialog onConfirm={handleConfirm} />\n * </Dialog.Root>\n * )\n * }\n * ```\n */\nconst ConfirmDialog = ({\n children,\n icon = <StyledWarning />,\n onConfirm,\n onCancel,\n variant = 'danger-light',\n startAction,\n endAction,\n title,\n}: ConfirmDialogProps) => {\n const { formatMessage } = useIntl();\n const [isConfirming, setIsConfirming] = React.useState(false);\n\n const content =\n children ||\n formatMessage({\n id: 'app.confirm.body',\n defaultMessage: 'Are you sure?',\n });\n\n const handleConfirm = async (e: React.MouseEvent<HTMLButtonElement>) => {\n if (!onConfirm) {\n return;\n }\n\n try {\n setIsConfirming(true);\n await onConfirm(e);\n } finally {\n setIsConfirming(false);\n }\n };\n\n return (\n <Dialog.Content>\n <Dialog.Header>\n {title ||\n formatMessage({\n id: 'app.components.ConfirmDialog.title',\n defaultMessage: 'Confirmation',\n })}\n </Dialog.Header>\n <Dialog.Body icon={icon}>{content}</Dialog.Body>\n <Dialog.Footer>\n {startAction || (\n <Dialog.Cancel>\n <Button\n fullWidth\n variant=\"tertiary\"\n onClick={(e) => {\n e.stopPropagation();\n if (onCancel) {\n onCancel(e);\n }\n }}\n >\n {formatMessage({\n id: 'app.components.Button.cancel',\n defaultMessage: 'Cancel',\n })}\n </Button>\n </Dialog.Cancel>\n )}\n {endAction || (\n <Dialog.Action>\n <Button fullWidth onClick={handleConfirm} variant={variant} loading={isConfirming}>\n {formatMessage({\n id: 'app.components.Button.confirm',\n defaultMessage: 'Confirm',\n })}\n </Button>\n </Dialog.Action>\n )}\n </Dialog.Footer>\n </Dialog.Content>\n );\n};\n\nconst StyledWarning = styled(WarningCircle)`\n width: 24px;\n height: 24px;\n\n path {\n fill: ${({ theme }) => theme.colors.danger600};\n }\n`;\n\nexport { ConfirmDialog };\nexport type { ConfirmDialogProps };\n"],"names":["ConfirmDialog","children","icon","_jsx","StyledWarning","onConfirm","onCancel","variant","startAction","endAction","title","formatMessage","useIntl","isConfirming","setIsConfirming","React","useState","content","id","defaultMessage","handleConfirm","e","_jsxs","Dialog","Content","Header","Body","Footer","Cancel","Button","fullWidth","onClick","stopPropagation","Action","loading","styled","WarningCircle","theme","colors","danger600"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAgCA,MAAMA,gBAAgB,CAAC,EACrBC,QAAQ,EACRC,IAAAA,iBAAOC,cAACC,CAAAA,aAAAA,EAAAA,EAAAA,CAAgB,EACxBC,SAAS,EACTC,QAAQ,EACRC,UAAU,cAAc,EACxBC,WAAW,EACXC,SAAS,EACTC,KAAK,EACc,GAAA;IACnB,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAM,CAACC,YAAcC,EAAAA,eAAAA,CAAgB,GLine truncated
@@ -0,0 +1,114 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import * as React from 'react';
import { Dialog, Button } from '@strapi/design-system';
import { WarningCircle } from '@strapi/icons';
import { useIntl } from 'react-intl';
import { styled } from 'styled-components';
/**
* @beta
* @public
* @description A simple confirm dialog that out of the box can be used to confirm an action.
* The component can additionally be customised if required e.g. the footer actions can be
* completely replaced, but cannot be removed. Passing a string as the children prop will render
* the string as the body of the dialog. If you need more control over the body, you can pass a
* custom component as the children prop.
* @example
* ```tsx
* import { Dialog } from '@strapi/design-system';
*
* const DeleteAction = ({ id }) => {
* const [isOpen, setIsOpen] = React.useState(false);
*
* const [delete] = useDeleteMutation()
* const handleConfirm = async () => {
* await delete(id)
* setIsOpen(false)
* }
*
* return (
* <Dialog.Root open={isOpen} onOpenChange={setIsOpen}>
* <Dialog.Trigger>
* <Button>Delete</Button>
* </Dialog.Trigger>
* <ConfirmDialog onConfirm={handleConfirm} />
* </Dialog.Root>
* )
* }
* ```
*/ const ConfirmDialog = ({ children, icon = /*#__PURE__*/ jsx(StyledWarning, {}), onConfirm, onCancel, variant = 'danger-light', startAction, endAction, title })=>{
const { formatMessage } = useIntl();
const [isConfirming, setIsConfirming] = React.useState(false);
const content = children || formatMessage({
id: 'app.confirm.body',
defaultMessage: 'Are you sure?'
});
const handleConfirm = async (e)=>{
if (!onConfirm) {
return;
}
try {
setIsConfirming(true);
await onConfirm(e);
} finally{
setIsConfirming(false);
}
};
return /*#__PURE__*/ jsxs(Dialog.Content, {
children: [
/*#__PURE__*/ jsx(Dialog.Header, {
children: title || formatMessage({
id: 'app.components.ConfirmDialog.title',
defaultMessage: 'Confirmation'
})
}),
/*#__PURE__*/ jsx(Dialog.Body, {
icon: icon,
children: content
}),
/*#__PURE__*/ jsxs(Dialog.Footer, {
children: [
startAction || /*#__PURE__*/ jsx(Dialog.Cancel, {
children: /*#__PURE__*/ jsx(Button, {
fullWidth: true,
variant: "tertiary",
onClick: (e)=>{
e.stopPropagation();
if (onCancel) {
onCancel(e);
}
},
children: formatMessage({
id: 'app.components.Button.cancel',
defaultMessage: 'Cancel'
})
})
}),
endAction || /*#__PURE__*/ jsx(Dialog.Action, {
children: /*#__PURE__*/ jsx(Button, {
fullWidth: true,
onClick: handleConfirm,
variant: variant,
loading: isConfirming,
children: formatMessage({
id: 'app.components.Button.confirm',
defaultMessage: 'Confirm'
})
})
})
]
})
]
});
};
const StyledWarning = styled(WarningCircle)`
width: 24px;
height: 24px;
path {
fill: ${({ theme })=>theme.colors.danger600};
}
`;
export { ConfirmDialog };
//# sourceMappingURL=ConfirmDialog.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"ConfirmDialog.mjs","sources":["../../../../../admin/src/components/ConfirmDialog.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Button, ButtonProps, Dialog } from '@strapi/design-system';\nimport { WarningCircle } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\n/* -------------------------------------------------------------------------------------------------\n * ConfirmDialog\n * -----------------------------------------------------------------------------------------------*/\ninterface ConfirmDialogProps extends Pick<ButtonProps, 'variant'>, Pick<Dialog.BodyProps, 'icon'> {\n onConfirm?: (e?: React.MouseEvent<HTMLButtonElement>) => Promise<void> | void;\n onCancel?: (e?: React.MouseEvent<HTMLButtonElement>) => Promise<void> | void;\n children?: React.ReactNode;\n endAction?: React.ReactNode;\n startAction?: React.ReactNode;\n title?: React.ReactNode;\n}\n\n/**\n * @beta\n * @public\n * @description A simple confirm dialog that out of the box can be used to confirm an action.\n * The component can additionally be customised if required e.g. the footer actions can be\n * completely replaced, but cannot be removed. Passing a string as the children prop will render\n * the string as the body of the dialog. If you need more control over the body, you can pass a\n * custom component as the children prop.\n * @example\n * ```tsx\n * import { Dialog } from '@strapi/design-system';\n *\n * const DeleteAction = ({ id }) => {\n * const [isOpen, setIsOpen] = React.useState(false);\n *\n * const [delete] = useDeleteMutation()\n * const handleConfirm = async () => {\n * await delete(id)\n * setIsOpen(false)\n * }\n *\n * return (\n * <Dialog.Root open={isOpen} onOpenChange={setIsOpen}>\n * <Dialog.Trigger>\n * <Button>Delete</Button>\n * </Dialog.Trigger>\n * <ConfirmDialog onConfirm={handleConfirm} />\n * </Dialog.Root>\n * )\n * }\n * ```\n */\nconst ConfirmDialog = ({\n children,\n icon = <StyledWarning />,\n onConfirm,\n onCancel,\n variant = 'danger-light',\n startAction,\n endAction,\n title,\n}: ConfirmDialogProps) => {\n const { formatMessage } = useIntl();\n const [isConfirming, setIsConfirming] = React.useState(false);\n\n const content =\n children ||\n formatMessage({\n id: 'app.confirm.body',\n defaultMessage: 'Are you sure?',\n });\n\n const handleConfirm = async (e: React.MouseEvent<HTMLButtonElement>) => {\n if (!onConfirm) {\n return;\n }\n\n try {\n setIsConfirming(true);\n await onConfirm(e);\n } finally {\n setIsConfirming(false);\n }\n };\n\n return (\n <Dialog.Content>\n <Dialog.Header>\n {title ||\n formatMessage({\n id: 'app.components.ConfirmDialog.title',\n defaultMessage: 'Confirmation',\n })}\n </Dialog.Header>\n <Dialog.Body icon={icon}>{content}</Dialog.Body>\n <Dialog.Footer>\n {startAction || (\n <Dialog.Cancel>\n <Button\n fullWidth\n variant=\"tertiary\"\n onClick={(e) => {\n e.stopPropagation();\n if (onCancel) {\n onCancel(e);\n }\n }}\n >\n {formatMessage({\n id: 'app.components.Button.cancel',\n defaultMessage: 'Cancel',\n })}\n </Button>\n </Dialog.Cancel>\n )}\n {endAction || (\n <Dialog.Action>\n <Button fullWidth onClick={handleConfirm} variant={variant} loading={isConfirming}>\n {formatMessage({\n id: 'app.components.Button.confirm',\n defaultMessage: 'Confirm',\n })}\n </Button>\n </Dialog.Action>\n )}\n </Dialog.Footer>\n </Dialog.Content>\n );\n};\n\nconst StyledWarning = styled(WarningCircle)`\n width: 24px;\n height: 24px;\n\n path {\n fill: ${({ theme }) => theme.colors.danger600};\n }\n`;\n\nexport { ConfirmDialog };\nexport type { ConfirmDialogProps };\n"],"names":["ConfirmDialog","children","icon","_jsx","StyledWarning","onConfirm","onCancel","variant","startAction","endAction","title","formatMessage","useIntl","isConfirming","setIsConfirming","React","useState","content","id","defaultMessage","handleConfirm","e","_jsxs","Dialog","Content","Header","Body","Footer","Cancel","Button","fullWidth","onClick","stopPropagation","Action","loading","styled","WarningCircle","theme","colors","danger600"],"mappings":";;;;;;;AAmBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAgCA,MAAMA,gBAAgB,CAAC,EACrBC,QAAQ,EACRC,IAAAA,iBAAOC,GAACC,CAAAA,aAAAA,EAAAA,EAAAA,CAAgB,EACxBC,SAAS,EACTC,QAAQ,EACRC,UAAU,cAAc,EACxBC,WAAW,EACXC,SAAS,EACTC,KAAK,EACc,GAAA;IACnB,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAC1B,IAAA,MAAM,CAACC,YAAcC,EAAAA,eAAAA,CAAgB,GAAGC,KAAAA,CAAMC,QAAQLine truncated
@@ -0,0 +1,61 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var designSystem = require('@strapi/design-system');
var styledComponents = require('styled-components');
const ContentBox = ({ title, subtitle, icon, iconBackground, endAction, titleEllipsis = false })=>{
if (title && title.length > 70 && titleEllipsis) {
title = `${title.substring(0, 70)}...`;
}
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
shadow: "tableShadow",
hasRadius: true,
padding: 6,
background: "neutral0",
children: [
/*#__PURE__*/ jsxRuntime.jsx(IconWrapper, {
background: iconBackground,
hasRadius: true,
padding: 3,
children: icon
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
direction: "column",
alignItems: "stretch",
gap: endAction ? 0 : 1,
children: [
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(TypographyWordBreak, {
fontWeight: "semiBold",
variant: "pi",
children: title
}),
endAction
]
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
textColor: "neutral600",
children: subtitle
})
]
})
]
});
};
const IconWrapper = styledComponents.styled(designSystem.Flex)`
margin-right: ${({ theme })=>theme.spaces[6]};
svg {
width: 3.2rem;
height: 3.2rem;
}
`;
const TypographyWordBreak = styledComponents.styled(designSystem.Typography)`
color: ${({ theme })=>theme.colors.neutral800};
word-break: break-all;
`;
exports.ContentBox = ContentBox;
//# sourceMappingURL=ContentBox.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ContentBox.js","sources":["../../../../../admin/src/components/ContentBox.tsx"],"sourcesContent":["import {\n Flex,\n FlexComponent,\n FlexProps,\n Typography,\n TypographyComponent,\n} from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\ninterface ContentBoxProps {\n title?: string;\n subtitle?: string;\n icon?: FlexProps['children'];\n iconBackground?: FlexProps['background'];\n endAction?: FlexProps['children'];\n titleEllipsis?: boolean;\n}\n\nconst ContentBox = ({\n title,\n subtitle,\n icon,\n iconBackground,\n endAction,\n titleEllipsis = false,\n}: ContentBoxProps) => {\n if (title && title.length > 70 && titleEllipsis) {\n title = `${title.substring(0, 70)}...`;\n }\n\n return (\n <Flex shadow=\"tableShadow\" hasRadius padding={6} background=\"neutral0\">\n <IconWrapper background={iconBackground} hasRadius padding={3}>\n {icon}\n </IconWrapper>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={endAction ? 0 : 1}>\n <Flex>\n <TypographyWordBreak fontWeight=\"semiBold\" variant=\"pi\">\n {title}\n </TypographyWordBreak>\n {endAction}\n </Flex>\n <Typography textColor=\"neutral600\">{subtitle}</Typography>\n </Flex>\n </Flex>\n );\n};\n\nconst IconWrapper = styled<FlexComponent>(Flex)`\n margin-right: ${({ theme }) => theme.spaces[6]};\n\n svg {\n width: 3.2rem;\n height: 3.2rem;\n }\n`;\n\nconst TypographyWordBreak = styled<TypographyComponent>(Typography)`\n color: ${({ theme }) => theme.colors.neutral800};\n word-break: break-all;\n`;\n\nexport { ContentBox };\nexport type { ContentBoxProps };\n"],"names":["ContentBox","title","subtitle","icon","iconBackground","endAction","titleEllipsis","length","substring","_jsxs","Flex","shadow","hasRadius","padding","background","_jsx","IconWrapper","direction","alignItems","gap","TypographyWordBreak","fontWeight","variant","Typography","textColor","styled","theme","spaces","colors","neutral800"],"mappings":";;;;;;AAkBA,MAAMA,UAAa,GAAA,CAAC,EAClBC,KAAK,EACLC,QAAQ,EACRC,IAAI,EACJC,cAAc,EACdC,SAAS,EACTC,aAAAA,GAAgB,KAAK,EACL,GAAA;AAChB,IAAA,IAAIL,KAASA,IAAAA,KAAAA,CAAMM,MAAM,GAAG,MAAMD,aAAe,EAAA;QAC/CL,KAAQ,GAAA,CAAC,EAAEA,KAAMO,CAAAA,SAAS,CAAC,CAAG,EAAA,EAAA,CAAA,CAAI,GAAG,CAAC;AACxC;AAEA,IAAA,qBACEC,eAACC,CAAAA,iBAAAA,EAAAA;QAAKC,MAAO,EAAA,aAAA;QAAcC,SAAS,EAAA,IAAA;QAACC,OAAS,EAAA,CAAA;QAAGC,UAAW,EAAA,UAAA;;0BAC1DC,cAACC,CAAAA,WAAAA,EAAAA;gBAAYF,UAAYV,EAAAA,cAAAA;gBAAgBQ,SAAS,EAAA,IAAA;gBAACC,OAAS,EAAA,CAAA;AACzDV,gBAAAA,QAAAA,EAAAA;;0BAEHM,eAACC,CAAAA,iBAAAA,EAAAA;gBAAKO,SAAU,EAAA,QAAA;gBAASC,UAAW,EAAA,SAAA;AAAUC,gBAAAA,GAAAA,EAAKd,YAAY,CAAI,GAAA,CAAA;;kCACjEI,eAACC,CAAAA,iBAAAA,EAAAA;;0CACCK,cAACK,CAAAA,mBAAAA,EAAAA;gCAAoBC,UAAW,EAAA,UAAA;gCAAWC,OAAQ,EAAA,IAAA;AAChDrB,gCAAAA,QAAAA,EAAAA;;AAEFI,4BAAAA;;;kCAEHU,cAACQ,CAAAA,uBAAAA,EAAAA;wBAAWC,SAAU,EAAA,YAAA;AAActB,wBAAAA,QAAAA,EAAAA;;;;;;AAI5C;AAEA,MAAMc,WAAAA,GAAcS,uBAAsBf,CAAAA,iBAAAA,CAAK;gBAC/B,EAAE,CAAC,EAAEgB,KAAK,EAAE,GAAKA,KAAMC,CAAAA,MAAM,CAAC,CAAA,CAAE,CAAC;;;;;;AAMjD,CAAC;AAED,MAAMP,mBAAAA,GAAsBK,uBAA4BF,CAAAA,uBAAAA,CAAW;SAC1D,EAAE,CAAC,EAAEG,KAAK,EAAE,GAAKA,KAAME,CAAAA,MAAM,CAACC,UAAU,CAAC;;AAElD,CAAC;;;;"}
@@ -0,0 +1,59 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import { Flex, Typography } from '@strapi/design-system';
import { styled } from 'styled-components';
const ContentBox = ({ title, subtitle, icon, iconBackground, endAction, titleEllipsis = false })=>{
if (title && title.length > 70 && titleEllipsis) {
title = `${title.substring(0, 70)}...`;
}
return /*#__PURE__*/ jsxs(Flex, {
shadow: "tableShadow",
hasRadius: true,
padding: 6,
background: "neutral0",
children: [
/*#__PURE__*/ jsx(IconWrapper, {
background: iconBackground,
hasRadius: true,
padding: 3,
children: icon
}),
/*#__PURE__*/ jsxs(Flex, {
direction: "column",
alignItems: "stretch",
gap: endAction ? 0 : 1,
children: [
/*#__PURE__*/ jsxs(Flex, {
children: [
/*#__PURE__*/ jsx(TypographyWordBreak, {
fontWeight: "semiBold",
variant: "pi",
children: title
}),
endAction
]
}),
/*#__PURE__*/ jsx(Typography, {
textColor: "neutral600",
children: subtitle
})
]
})
]
});
};
const IconWrapper = styled(Flex)`
margin-right: ${({ theme })=>theme.spaces[6]};
svg {
width: 3.2rem;
height: 3.2rem;
}
`;
const TypographyWordBreak = styled(Typography)`
color: ${({ theme })=>theme.colors.neutral800};
word-break: break-all;
`;
export { ContentBox };
//# sourceMappingURL=ContentBox.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"ContentBox.mjs","sources":["../../../../../admin/src/components/ContentBox.tsx"],"sourcesContent":["import {\n Flex,\n FlexComponent,\n FlexProps,\n Typography,\n TypographyComponent,\n} from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\ninterface ContentBoxProps {\n title?: string;\n subtitle?: string;\n icon?: FlexProps['children'];\n iconBackground?: FlexProps['background'];\n endAction?: FlexProps['children'];\n titleEllipsis?: boolean;\n}\n\nconst ContentBox = ({\n title,\n subtitle,\n icon,\n iconBackground,\n endAction,\n titleEllipsis = false,\n}: ContentBoxProps) => {\n if (title && title.length > 70 && titleEllipsis) {\n title = `${title.substring(0, 70)}...`;\n }\n\n return (\n <Flex shadow=\"tableShadow\" hasRadius padding={6} background=\"neutral0\">\n <IconWrapper background={iconBackground} hasRadius padding={3}>\n {icon}\n </IconWrapper>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={endAction ? 0 : 1}>\n <Flex>\n <TypographyWordBreak fontWeight=\"semiBold\" variant=\"pi\">\n {title}\n </TypographyWordBreak>\n {endAction}\n </Flex>\n <Typography textColor=\"neutral600\">{subtitle}</Typography>\n </Flex>\n </Flex>\n );\n};\n\nconst IconWrapper = styled<FlexComponent>(Flex)`\n margin-right: ${({ theme }) => theme.spaces[6]};\n\n svg {\n width: 3.2rem;\n height: 3.2rem;\n }\n`;\n\nconst TypographyWordBreak = styled<TypographyComponent>(Typography)`\n color: ${({ theme }) => theme.colors.neutral800};\n word-break: break-all;\n`;\n\nexport { ContentBox };\nexport type { ContentBoxProps };\n"],"names":["ContentBox","title","subtitle","icon","iconBackground","endAction","titleEllipsis","length","substring","_jsxs","Flex","shadow","hasRadius","padding","background","_jsx","IconWrapper","direction","alignItems","gap","TypographyWordBreak","fontWeight","variant","Typography","textColor","styled","theme","spaces","colors","neutral800"],"mappings":";;;;AAkBA,MAAMA,UAAa,GAAA,CAAC,EAClBC,KAAK,EACLC,QAAQ,EACRC,IAAI,EACJC,cAAc,EACdC,SAAS,EACTC,aAAAA,GAAgB,KAAK,EACL,GAAA;AAChB,IAAA,IAAIL,KAASA,IAAAA,KAAAA,CAAMM,MAAM,GAAG,MAAMD,aAAe,EAAA;QAC/CL,KAAQ,GAAA,CAAC,EAAEA,KAAMO,CAAAA,SAAS,CAAC,CAAG,EAAA,EAAA,CAAA,CAAI,GAAG,CAAC;AACxC;AAEA,IAAA,qBACEC,IAACC,CAAAA,IAAAA,EAAAA;QAAKC,MAAO,EAAA,aAAA;QAAcC,SAAS,EAAA,IAAA;QAACC,OAAS,EAAA,CAAA;QAAGC,UAAW,EAAA,UAAA;;0BAC1DC,GAACC,CAAAA,WAAAA,EAAAA;gBAAYF,UAAYV,EAAAA,cAAAA;gBAAgBQ,SAAS,EAAA,IAAA;gBAACC,OAAS,EAAA,CAAA;AACzDV,gBAAAA,QAAAA,EAAAA;;0BAEHM,IAACC,CAAAA,IAAAA,EAAAA;gBAAKO,SAAU,EAAA,QAAA;gBAASC,UAAW,EAAA,SAAA;AAAUC,gBAAAA,GAAAA,EAAKd,YAAY,CAAI,GAAA,CAAA;;kCACjEI,IAACC,CAAAA,IAAAA,EAAAA;;0CACCK,GAACK,CAAAA,mBAAAA,EAAAA;gCAAoBC,UAAW,EAAA,UAAA;gCAAWC,OAAQ,EAAA,IAAA;AAChDrB,gCAAAA,QAAAA,EAAAA;;AAEFI,4BAAAA;;;kCAEHU,GAACQ,CAAAA,UAAAA,EAAAA;wBAAWC,SAAU,EAAA,YAAA;AAActB,wBAAAA,QAAAA,EAAAA;;;;;;AAI5C;AAEA,MAAMc,WAAAA,GAAcS,MAAsBf,CAAAA,IAAAA,CAAK;gBAC/B,EAAE,CAAC,EAAEgB,KAAK,EAAE,GAAKA,KAAMC,CAAAA,MAAM,CAAC,CAAA,CAAE,CAAC;;;;;;AAMjD,CAAC;AAED,MAAMP,mBAAAA,GAAsBK,MAA4BF,CAAAA,UAAAA,CAAW;SAC1D,EAAE,CAAC,EAAEG,KAAK,EAAE,GAAKA,KAAME,CAAAA,MAAM,CAACC,UAAU,CAAC;;AAElD,CAAC;;;;"}
@@ -0,0 +1,63 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var ContextSelector = require('use-context-selector');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
var ContextSelector__namespace = /*#__PURE__*/_interopNamespaceDefault(ContextSelector);
/**
* @experimental
* @description Create a context provider and a hook to consume the context.
*
* @warning this may be removed to the design-system instead of becoming stable.
*/ function createContext(rootComponentName, defaultContext) {
const Context = ContextSelector__namespace.createContext(defaultContext);
const Provider = (props)=>{
const { children, ...context } = props;
// Only re-memoize when prop values change
// eslint-disable-next-line react-hooks/exhaustive-deps
const value = React__namespace.useMemo(()=>context, Object.values(context));
return /*#__PURE__*/ jsxRuntime.jsx(Context.Provider, {
value: value,
children: children
});
};
function useContext(consumerName, selector, shouldThrowOnMissingContext) {
return ContextSelector__namespace.useContextSelector(Context, (ctx)=>{
// The context is available, return the selected value
if (ctx) return selector(ctx);
// The context is not available, either return undefined or throw an error
if (shouldThrowOnMissingContext) {
throw new Error(`\`${consumerName}\` must be used within \`${rootComponentName}\``);
}
return undefined;
});
}
Provider.displayName = rootComponentName + 'Provider';
return [
Provider,
useContext
];
}
exports.createContext = createContext;
//# sourceMappingURL=Context.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Context.js","sources":["../../../../../admin/src/components/Context.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport * as ContextSelector from 'use-context-selector';\n\n/**\n * @experimental\n * @description Create a context provider and a hook to consume the context.\n *\n * @warning this may be removed to the design-system instead of becoming stable.\n */\nfunction createContext<ContextValueType extends object | null>(\n rootComponentName: string,\n defaultContext?: ContextValueType\n) {\n const Context = ContextSelector.createContext<ContextValueType | undefined>(defaultContext);\n\n const Provider = (props: ContextValueType & { children: React.ReactNode }) => {\n const { children, ...context } = props;\n // Only re-memoize when prop values change\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const value = React.useMemo(() => context, Object.values(context)) as ContextValueType;\n\n return <Context.Provider value={value}>{children}</Context.Provider>;\n };\n\n function useContext<Selected, ShouldThrow extends boolean = true>(\n consumerName: string,\n selector: (value: ContextValueType) => Selected,\n shouldThrowOnMissingContext?: ShouldThrow\n ) {\n return ContextSelector.useContextSelector(Context, (ctx) => {\n // The context is available, return the selected value\n if (ctx) return selector(ctx);\n\n // The context is not available, either return undefined or throw an error\n if (shouldThrowOnMissingContext) {\n throw new Error(`\\`${consumerName}\\` must be used within \\`${rootComponentName}\\``);\n }\n\n return undefined;\n }) as ShouldThrow extends true ? Selected : Selected | undefined;\n }\n\n Provider.displayName = rootComponentName + 'Provider';\n\n return [Provider, useContext] as const;\n}\n\nexport { createContext };\n"],"names":["createContext","rootComponentName","defaultContext","Context","ContextSelector","Provider","props","children","context","value","React","useMemo","Object","values","_jsx","useContext","consumerName","selector","shouldThrowOnMissingContext","useContextSelector","ctx","Error","undefined","displayName"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAIA;;;;;AAKC,IACD,SAASA,aAAAA,CACPC,iBAAyB,EACzBC,cAAiC,EAAA;IAEjC,MAAMC,OAAAA,GAAUC,0BAAgBJ,CAAAA,aAAa,CAA+BE,cAAAA,CAAAA;AAE5E,IAAA,MAAMG,WAAW,CAACC,KAAAA,GAAAA;AAChB,QAAA,MAAM,EAAEC,QAAQ,EAAE,GAAGC,SAAS,GAAGF,KAAAA;;;QAGjC,MAAMG,KAAAA,GAAQC,iBAAMC,OAAO,CAAC,IAAMH,OAASI,EAAAA,MAAAA,CAAOC,MAAM,CAACL,OAAAA,CAAAA,CAAAA;QAEzD,qBAAOM,cAAA,CAACX,QAAQE,QAAQ,EAAA;YAACI,KAAOA,EAAAA,KAAAA;AAAQF,YAAAA,QAAAA,EAAAA;;AAC1C,KAAA;AAEA,IAAA,SAASQ,UACPC,CAAAA,YAAoB,EACpBC,QAA+C,EAC/CC,2BAAyC,EAAA;AAEzC,QAAA,OAAOd,0BAAgBe,CAAAA,kBAAkB,CAAChB,OAAAA,EAAS,CAACiB,GAAAA,GAAAA;;YAElD,IAAIA,GAAAA,EAAK,OAAOH,QAASG,CAAAA,GAAAA,CAAAA;;AAGzB,YAAA,IAAIF,2BAA6B,EAAA;gBAC/B,MAAM,IAAIG,KAAM,CAAA,CAAC,EAAE,EAAEL,aAAa,yBAAyB,EAAEf,iBAAkB,CAAA,EAAE,CAAC,CAAA;AACpF;YAEA,OAAOqB,SAAAA;AACT,SAAA,CAAA;AACF;IAEAjB,QAASkB,CAAAA,WAAW,GAAGtB,iBAAoB,GAAA,UAAA;IAE3C,OAAO;AAACI,QAAAA,QAAAA;AAAUU,QAAAA;AAAW,KAAA;AAC/B;;;;"}
@@ -0,0 +1,41 @@
import { jsx } from 'react/jsx-runtime';
import * as React from 'react';
import * as ContextSelector from 'use-context-selector';
/**
* @experimental
* @description Create a context provider and a hook to consume the context.
*
* @warning this may be removed to the design-system instead of becoming stable.
*/ function createContext(rootComponentName, defaultContext) {
const Context = ContextSelector.createContext(defaultContext);
const Provider = (props)=>{
const { children, ...context } = props;
// Only re-memoize when prop values change
// eslint-disable-next-line react-hooks/exhaustive-deps
const value = React.useMemo(()=>context, Object.values(context));
return /*#__PURE__*/ jsx(Context.Provider, {
value: value,
children: children
});
};
function useContext(consumerName, selector, shouldThrowOnMissingContext) {
return ContextSelector.useContextSelector(Context, (ctx)=>{
// The context is available, return the selected value
if (ctx) return selector(ctx);
// The context is not available, either return undefined or throw an error
if (shouldThrowOnMissingContext) {
throw new Error(`\`${consumerName}\` must be used within \`${rootComponentName}\``);
}
return undefined;
});
}
Provider.displayName = rootComponentName + 'Provider';
return [
Provider,
useContext
];
}
export { createContext };
//# sourceMappingURL=Context.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"Context.mjs","sources":["../../../../../admin/src/components/Context.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport * as ContextSelector from 'use-context-selector';\n\n/**\n * @experimental\n * @description Create a context provider and a hook to consume the context.\n *\n * @warning this may be removed to the design-system instead of becoming stable.\n */\nfunction createContext<ContextValueType extends object | null>(\n rootComponentName: string,\n defaultContext?: ContextValueType\n) {\n const Context = ContextSelector.createContext<ContextValueType | undefined>(defaultContext);\n\n const Provider = (props: ContextValueType & { children: React.ReactNode }) => {\n const { children, ...context } = props;\n // Only re-memoize when prop values change\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const value = React.useMemo(() => context, Object.values(context)) as ContextValueType;\n\n return <Context.Provider value={value}>{children}</Context.Provider>;\n };\n\n function useContext<Selected, ShouldThrow extends boolean = true>(\n consumerName: string,\n selector: (value: ContextValueType) => Selected,\n shouldThrowOnMissingContext?: ShouldThrow\n ) {\n return ContextSelector.useContextSelector(Context, (ctx) => {\n // The context is available, return the selected value\n if (ctx) return selector(ctx);\n\n // The context is not available, either return undefined or throw an error\n if (shouldThrowOnMissingContext) {\n throw new Error(`\\`${consumerName}\\` must be used within \\`${rootComponentName}\\``);\n }\n\n return undefined;\n }) as ShouldThrow extends true ? Selected : Selected | undefined;\n }\n\n Provider.displayName = rootComponentName + 'Provider';\n\n return [Provider, useContext] as const;\n}\n\nexport { createContext };\n"],"names":["createContext","rootComponentName","defaultContext","Context","ContextSelector","Provider","props","children","context","value","React","useMemo","Object","values","_jsx","useContext","consumerName","selector","shouldThrowOnMissingContext","useContextSelector","ctx","Error","undefined","displayName"],"mappings":";;;;AAIA;;;;;AAKC,IACD,SAASA,aAAAA,CACPC,iBAAyB,EACzBC,cAAiC,EAAA;IAEjC,MAAMC,OAAAA,GAAUC,eAAgBJ,CAAAA,aAAa,CAA+BE,cAAAA,CAAAA;AAE5E,IAAA,MAAMG,WAAW,CAACC,KAAAA,GAAAA;AAChB,QAAA,MAAM,EAAEC,QAAQ,EAAE,GAAGC,SAAS,GAAGF,KAAAA;;;QAGjC,MAAMG,KAAAA,GAAQC,MAAMC,OAAO,CAAC,IAAMH,OAASI,EAAAA,MAAAA,CAAOC,MAAM,CAACL,OAAAA,CAAAA,CAAAA;QAEzD,qBAAOM,GAAA,CAACX,QAAQE,QAAQ,EAAA;YAACI,KAAOA,EAAAA,KAAAA;AAAQF,YAAAA,QAAAA,EAAAA;;AAC1C,KAAA;AAEA,IAAA,SAASQ,UACPC,CAAAA,YAAoB,EACpBC,QAA+C,EAC/CC,2BAAyC,EAAA;AAEzC,QAAA,OAAOd,eAAgBe,CAAAA,kBAAkB,CAAChB,OAAAA,EAAS,CAACiB,GAAAA,GAAAA;;YAElD,IAAIA,GAAAA,EAAK,OAAOH,QAASG,CAAAA,GAAAA,CAAAA;;AAGzB,YAAA,IAAIF,2BAA6B,EAAA;gBAC/B,MAAM,IAAIG,KAAM,CAAA,CAAC,EAAE,EAAEL,aAAa,yBAAyB,EAAEf,iBAAkB,CAAA,EAAE,CAAC,CAAA;AACpF;YAEA,OAAOqB,SAAAA;AACT,SAAA,CAAA;AACF;IAEAjB,QAASkB,CAAAA,WAAW,GAAGtB,iBAAoB,GAAA,UAAA;IAE3C,OAAO;AAACI,QAAAA,QAAAA;AAAUU,QAAAA;AAAW,KAAA;AAC/B;;;;"}
@@ -0,0 +1,144 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var isEqual = require('lodash/isEqual');
var useForceUpdate = require('../hooks/useForceUpdate.js');
var useThrottledCallback = require('../hooks/useThrottledCallback.js');
var shims = require('../utils/shims.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
/**
* @internal
*
* @description This component takes an array of DescriptionComponents, which are react components that return objects as opposed to JSX.
* We render these in their own isolated memoized component and use an update function to push the data back out to the parent.
* Saving it in a ref, and then "forcing" an update of the parent component to render the children of this component with the new data.
*
* The DescriptionCompoonents can take props and use react hooks hence why we render them as if they were a component. The update
* function is throttled and managed to avoid erroneous updates where we could wait a single tick to update the entire UI, which
* creates less "popping" from functions being called in rapid succession.
*/ const DescriptionComponentRenderer = ({ children, props, descriptions })=>{
const statesRef = React__namespace.useRef({});
const [tick, forceUpdate] = useForceUpdate.useForceUpdate();
const requestHandle = React__namespace.useRef(null);
const requestUpdate = React__namespace.useCallback(()=>{
if (requestHandle.current) {
shims.cancelIdleCallback(requestHandle.current);
}
requestHandle.current = shims.requestIdleCallback(()=>{
requestHandle.current = null;
forceUpdate();
});
}, [
forceUpdate
]);
/**
* This will avoid us calling too many react updates in a short space of time.
*/ const throttledRequestUpdate = useThrottledCallback.useThrottledCallback(requestUpdate, 60, {
trailing: true
});
const update = React__namespace.useCallback((id, description)=>{
if (description === null) {
delete statesRef.current[id];
} else {
const current = statesRef.current[id];
statesRef.current[id] = {
...current,
value: {
...description,
id
}
};
}
throttledRequestUpdate();
}, [
throttledRequestUpdate
]);
const ids = React__namespace.useMemo(()=>descriptions.map((description)=>getCompId(description)), [
descriptions
]);
const states = React__namespace.useMemo(()=>ids.map((id)=>statesRef.current[id]?.value).filter((state)=>state !== null && state !== undefined), /**
* we leave tick in the deps to ensure the memo is recalculated when the `update` function is called.
* the `ids` will most likely be stable unless we get new actions, but we can't respond to the Description
* Component changing the ref data in any other way.
*/ // eslint-disable-next-line react-hooks/exhaustive-deps
[
ids,
tick
]);
return /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
children: [
descriptions.map((description)=>{
const key = getCompId(description);
return /*#__PURE__*/ jsxRuntime.jsx(Description, {
id: key,
description: description,
props: props,
update: update
}, key);
}),
children(states)
]
});
};
/**
* Descriptions are objects, but to create the object, we allow users to create components,
* this means they can use react hooks in them. It also means we need to render them
* within a component, however because they return an object of data we can't add that
* to the react tree, instead we push it back out to the parent.
*/ const Description = /*#__PURE__*/ React__namespace.memo(({ description, id, props, update })=>{
const comp = description(props);
useShallowCompareEffect(()=>{
update(id, comp);
return ()=>{
update(id, null);
};
}, comp);
return null;
}, (prev, next)=>isEqual(prev.props, next.props));
/* -------------------------------------------------------------------------------------------------
* Helpers
* -----------------------------------------------------------------------------------------------*/ const ids = new WeakMap();
let counter = 0;
function getCompId(comp) {
const cachedId = ids.get(comp);
if (cachedId) return cachedId;
const id = `${comp.name || comp.displayName || '<anonymous>'}-${counter++}`;
ids.set(comp, id);
return id;
}
const useShallowCompareMemoize = (value)=>{
const ref = React__namespace.useRef(undefined);
if (!isEqual(value, ref.current)) {
ref.current = value;
}
return [
ref.current
];
};
const useShallowCompareEffect = (callback, dependencies)=>{
// eslint-disable-next-line react-hooks/exhaustive-deps -- the linter isn't able to see that deps are properly handled here
React__namespace.useEffect(callback, useShallowCompareMemoize(dependencies));
};
exports.DescriptionComponentRenderer = DescriptionComponentRenderer;
//# sourceMappingURL=DescriptionComponentRenderer.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DescriptionComponentRenderer.js","sources":["../../../../../admin/src/components/DescriptionComponentRenderer.tsx"],"sourcesContent":["/**\n * This component will render DescriptionComponents that return objects e.g. `cm.apis.addEditViewPanel`\n * these descriptions are still treated like components because users can use react hooks in them.\n *\n * Rendering them normally by mapping etc. causes mutliple render issues.\n */\n\nimport * as React from 'react';\n\nimport isEqual from 'lodash/isEqual';\n\nimport { useForceUpdate } from '../hooks/useForceUpdate';\nimport { useThrottledCallback } from '../hooks/useThrottledCallback';\nimport { cancelIdleCallback, requestIdleCallback } from '../utils/shims';\n\ninterface DescriptionComponent<Props, Description> {\n (props: Props): Description | null;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * DescriptionComponentRenderer\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DescriptionComponentRendererProps<Props = any, Description = any> {\n children: (descriptions: Array<Description & { id: string }>) => React.ReactNode;\n descriptions: DescriptionComponent<Props, Description>[];\n props: Props;\n}\n\n/**\n * @internal\n *\n * @description This component takes an array of DescriptionComponents, which are react components that return objects as opposed to JSX.\n * We render these in their own isolated memoized component and use an update function to push the data back out to the parent.\n * Saving it in a ref, and then \"forcing\" an update of the parent component to render the children of this component with the new data.\n *\n * The DescriptionCompoonents can take props and use react hooks hence why we render them as if they were a component. The update\n * function is throttled and managed to avoid erroneous updates where we could wait a single tick to update the entire UI, which\n * creates less \"popping\" from functions being called in rapid succession.\n */\nconst DescriptionComponentRenderer = <Props, Description>({\n children,\n props,\n descriptions,\n}: DescriptionComponentRendererProps<Props, Description>) => {\n const statesRef = React.useRef<Record<string, { value: Description & { id: string } }>>({});\n const [tick, forceUpdate] = useForceUpdate();\n\n const requestHandle = React.useRef<number | null>(null);\n const requestUpdate = React.useCallback(() => {\n if (requestHandle.current) {\n cancelIdleCallback(requestHandle.current);\n }\n\n requestHandle.current = requestIdleCallback(() => {\n requestHandle.current = null;\n\n forceUpdate();\n });\n }, [forceUpdate]);\n\n /**\n * This will avoid us calling too many react updates in a short space of time.\n */\n const throttledRequestUpdate = useThrottledCallback(requestUpdate, 60, { trailing: true });\n\n const update = React.useCallback<DescriptionProps<Props, Description>['update']>(\n (id, description) => {\n if (description === null) {\n delete statesRef.current[id];\n } else {\n const current = statesRef.current[id];\n statesRef.current[id] = { ...current, value: { ...description, id } };\n }\n\n throttledRequestUpdate();\n },\n [throttledRequestUpdate]\n );\n\n const ids = React.useMemo(\n () => descriptions.map((description) => getCompId(description)),\n [descriptions]\n );\n\n const states = React.useMemo(\n () =>\n ids\n .map((id) => statesRef.current[id]?.value)\n .filter((state) => state !== null && state !== undefined),\n /**\n * we leave tick in the deps to ensure the memo is recalculated when the `update` function is called.\n * the `ids` will most likely be stable unless we get new actions, but we can't respond to the Description\n * Component changing the ref data in any other way.\n */\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [ids, tick]\n );\n\n return (\n <>\n {descriptions.map((description) => {\n const key = getCompId(description);\n return (\n <Description key={key} id={key} description={description} props={props} update={update} />\n );\n })}\n {children(states)}\n </>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Description\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DescriptionProps<Props, Description> {\n description: DescriptionComponent<Props, Description>;\n id: string;\n props: Props;\n update: (id: string, value: Description | null) => void;\n}\n\n/**\n * Descriptions are objects, but to create the object, we allow users to create components,\n * this means they can use react hooks in them. It also means we need to render them\n * within a component, howLine truncated
@@ -0,0 +1,123 @@
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
import * as React from 'react';
import isEqual from 'lodash/isEqual';
import { useForceUpdate } from '../hooks/useForceUpdate.mjs';
import { useThrottledCallback } from '../hooks/useThrottledCallback.mjs';
import { cancelIdleCallback as _cancelIdleCallback, requestIdleCallback as _requestIdleCallback } from '../utils/shims.mjs';
/**
* @internal
*
* @description This component takes an array of DescriptionComponents, which are react components that return objects as opposed to JSX.
* We render these in their own isolated memoized component and use an update function to push the data back out to the parent.
* Saving it in a ref, and then "forcing" an update of the parent component to render the children of this component with the new data.
*
* The DescriptionCompoonents can take props and use react hooks hence why we render them as if they were a component. The update
* function is throttled and managed to avoid erroneous updates where we could wait a single tick to update the entire UI, which
* creates less "popping" from functions being called in rapid succession.
*/ const DescriptionComponentRenderer = ({ children, props, descriptions })=>{
const statesRef = React.useRef({});
const [tick, forceUpdate] = useForceUpdate();
const requestHandle = React.useRef(null);
const requestUpdate = React.useCallback(()=>{
if (requestHandle.current) {
_cancelIdleCallback(requestHandle.current);
}
requestHandle.current = _requestIdleCallback(()=>{
requestHandle.current = null;
forceUpdate();
});
}, [
forceUpdate
]);
/**
* This will avoid us calling too many react updates in a short space of time.
*/ const throttledRequestUpdate = useThrottledCallback(requestUpdate, 60, {
trailing: true
});
const update = React.useCallback((id, description)=>{
if (description === null) {
delete statesRef.current[id];
} else {
const current = statesRef.current[id];
statesRef.current[id] = {
...current,
value: {
...description,
id
}
};
}
throttledRequestUpdate();
}, [
throttledRequestUpdate
]);
const ids = React.useMemo(()=>descriptions.map((description)=>getCompId(description)), [
descriptions
]);
const states = React.useMemo(()=>ids.map((id)=>statesRef.current[id]?.value).filter((state)=>state !== null && state !== undefined), /**
* we leave tick in the deps to ensure the memo is recalculated when the `update` function is called.
* the `ids` will most likely be stable unless we get new actions, but we can't respond to the Description
* Component changing the ref data in any other way.
*/ // eslint-disable-next-line react-hooks/exhaustive-deps
[
ids,
tick
]);
return /*#__PURE__*/ jsxs(Fragment, {
children: [
descriptions.map((description)=>{
const key = getCompId(description);
return /*#__PURE__*/ jsx(Description, {
id: key,
description: description,
props: props,
update: update
}, key);
}),
children(states)
]
});
};
/**
* Descriptions are objects, but to create the object, we allow users to create components,
* this means they can use react hooks in them. It also means we need to render them
* within a component, however because they return an object of data we can't add that
* to the react tree, instead we push it back out to the parent.
*/ const Description = /*#__PURE__*/ React.memo(({ description, id, props, update })=>{
const comp = description(props);
useShallowCompareEffect(()=>{
update(id, comp);
return ()=>{
update(id, null);
};
}, comp);
return null;
}, (prev, next)=>isEqual(prev.props, next.props));
/* -------------------------------------------------------------------------------------------------
* Helpers
* -----------------------------------------------------------------------------------------------*/ const ids = new WeakMap();
let counter = 0;
function getCompId(comp) {
const cachedId = ids.get(comp);
if (cachedId) return cachedId;
const id = `${comp.name || comp.displayName || '<anonymous>'}-${counter++}`;
ids.set(comp, id);
return id;
}
const useShallowCompareMemoize = (value)=>{
const ref = React.useRef(undefined);
if (!isEqual(value, ref.current)) {
ref.current = value;
}
return [
ref.current
];
};
const useShallowCompareEffect = (callback, dependencies)=>{
// eslint-disable-next-line react-hooks/exhaustive-deps -- the linter isn't able to see that deps are properly handled here
React.useEffect(callback, useShallowCompareMemoize(dependencies));
};
export { DescriptionComponentRenderer };
//# sourceMappingURL=DescriptionComponentRenderer.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"DescriptionComponentRenderer.mjs","sources":["../../../../../admin/src/components/DescriptionComponentRenderer.tsx"],"sourcesContent":["/**\n * This component will render DescriptionComponents that return objects e.g. `cm.apis.addEditViewPanel`\n * these descriptions are still treated like components because users can use react hooks in them.\n *\n * Rendering them normally by mapping etc. causes mutliple render issues.\n */\n\nimport * as React from 'react';\n\nimport isEqual from 'lodash/isEqual';\n\nimport { useForceUpdate } from '../hooks/useForceUpdate';\nimport { useThrottledCallback } from '../hooks/useThrottledCallback';\nimport { cancelIdleCallback, requestIdleCallback } from '../utils/shims';\n\ninterface DescriptionComponent<Props, Description> {\n (props: Props): Description | null;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * DescriptionComponentRenderer\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DescriptionComponentRendererProps<Props = any, Description = any> {\n children: (descriptions: Array<Description & { id: string }>) => React.ReactNode;\n descriptions: DescriptionComponent<Props, Description>[];\n props: Props;\n}\n\n/**\n * @internal\n *\n * @description This component takes an array of DescriptionComponents, which are react components that return objects as opposed to JSX.\n * We render these in their own isolated memoized component and use an update function to push the data back out to the parent.\n * Saving it in a ref, and then \"forcing\" an update of the parent component to render the children of this component with the new data.\n *\n * The DescriptionCompoonents can take props and use react hooks hence why we render them as if they were a component. The update\n * function is throttled and managed to avoid erroneous updates where we could wait a single tick to update the entire UI, which\n * creates less \"popping\" from functions being called in rapid succession.\n */\nconst DescriptionComponentRenderer = <Props, Description>({\n children,\n props,\n descriptions,\n}: DescriptionComponentRendererProps<Props, Description>) => {\n const statesRef = React.useRef<Record<string, { value: Description & { id: string } }>>({});\n const [tick, forceUpdate] = useForceUpdate();\n\n const requestHandle = React.useRef<number | null>(null);\n const requestUpdate = React.useCallback(() => {\n if (requestHandle.current) {\n cancelIdleCallback(requestHandle.current);\n }\n\n requestHandle.current = requestIdleCallback(() => {\n requestHandle.current = null;\n\n forceUpdate();\n });\n }, [forceUpdate]);\n\n /**\n * This will avoid us calling too many react updates in a short space of time.\n */\n const throttledRequestUpdate = useThrottledCallback(requestUpdate, 60, { trailing: true });\n\n const update = React.useCallback<DescriptionProps<Props, Description>['update']>(\n (id, description) => {\n if (description === null) {\n delete statesRef.current[id];\n } else {\n const current = statesRef.current[id];\n statesRef.current[id] = { ...current, value: { ...description, id } };\n }\n\n throttledRequestUpdate();\n },\n [throttledRequestUpdate]\n );\n\n const ids = React.useMemo(\n () => descriptions.map((description) => getCompId(description)),\n [descriptions]\n );\n\n const states = React.useMemo(\n () =>\n ids\n .map((id) => statesRef.current[id]?.value)\n .filter((state) => state !== null && state !== undefined),\n /**\n * we leave tick in the deps to ensure the memo is recalculated when the `update` function is called.\n * the `ids` will most likely be stable unless we get new actions, but we can't respond to the Description\n * Component changing the ref data in any other way.\n */\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [ids, tick]\n );\n\n return (\n <>\n {descriptions.map((description) => {\n const key = getCompId(description);\n return (\n <Description key={key} id={key} description={description} props={props} update={update} />\n );\n })}\n {children(states)}\n </>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Description\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DescriptionProps<Props, Description> {\n description: DescriptionComponent<Props, Description>;\n id: string;\n props: Props;\n update: (id: string, value: Description | null) => void;\n}\n\n/**\n * Descriptions are objects, but to create the object, we allow users to create components,\n * this means they can use react hooks in them. It also means we need to render them\n * within a component, hoLine truncated
@@ -0,0 +1,127 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var reactIntl = require('react-intl');
var reactRouterDom = require('react-router-dom');
var styledComponents = require('styled-components');
var useClipboard = require('../hooks/useClipboard.js');
/**
* @description this stops the app from going white, and instead shows the error message.
* But it could be improved for sure.
*/ const ErrorElement = ()=>{
const error = reactRouterDom.useRouteError();
const { formatMessage } = reactIntl.useIntl();
const { copy } = useClipboard.useClipboard();
if (error instanceof Error) {
console.error(error);
const handleClick = async ()=>{
await copy(`
\`\`\`
${error.stack}
\`\`\`
`);
};
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Main, {
height: "100%",
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
alignItems: "center",
height: "100%",
justifyContent: "center",
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
gap: 7,
padding: 7,
direction: "column",
width: "35%",
shadow: "tableShadow",
borderColor: "neutral150",
background: "neutral0",
hasRadius: true,
maxWidth: "512px",
children: [
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
direction: "column",
gap: 2,
children: [
/*#__PURE__*/ jsxRuntime.jsx(icons.WarningCircle, {
width: "32px",
height: "32px",
fill: "danger600"
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
fontSize: 4,
fontWeight: "bold",
textAlign: "center",
children: formatMessage({
id: 'app.error',
defaultMessage: 'Something went wrong'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "omega",
textAlign: "center",
children: formatMessage({
id: 'app.error.message',
defaultMessage: `It seems like there is a bug in your instance, but we've got you covered. Please notify your technical team so they can investigate the source of the problem and report the issue to us by opening a bug report on {link}.`
}, {
link: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Link, {
isExternal: true,
// hack to get rid of the current endIcon, which should be removable by using `null`.
endIcon: true,
href: "https://github.com/strapi/strapi/issues/new?assignees=&labels=&projects=&template=BUG_REPORT.md",
children: `Strapi's GitHub`
})
})
})
]
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
gap: 4,
direction: "column",
width: "100%",
children: [
/*#__PURE__*/ jsxRuntime.jsx(StyledAlert, {
onClose: ()=>{},
width: "100%",
closeLabel: "",
variant: "danger",
children: /*#__PURE__*/ jsxRuntime.jsx(ErrorType, {
children: error.message
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
onClick: handleClick,
variant: "tertiary",
startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.Duplicate, {}),
children: formatMessage({
id: 'app.error.copy',
defaultMessage: 'Copy to clipboard'
})
})
]
})
]
})
})
});
}
throw error;
};
const StyledAlert = styledComponents.styled(designSystem.Alert)`
& > div:first-child {
display: none;
}
& > button {
display: none;
}
`;
const ErrorType = styledComponents.styled(designSystem.Typography)`
word-break: break-all;
color: ${({ theme })=>theme.colors.danger600};
`;
exports.ErrorElement = ErrorElement;
//# sourceMappingURL=ErrorElement.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ErrorElement.js","sources":["../../../../../admin/src/components/ErrorElement.tsx"],"sourcesContent":["import {\n Alert,\n Button,\n Flex,\n Main,\n Typography,\n Link,\n TypographyComponent,\n} from '@strapi/design-system';\nimport { Duplicate, WarningCircle } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { useRouteError } from 'react-router-dom';\nimport { styled } from 'styled-components';\n\nimport { useClipboard } from '../hooks/useClipboard';\n\n/**\n * @description this stops the app from going white, and instead shows the error message.\n * But it could be improved for sure.\n */\nconst ErrorElement = () => {\n const error = useRouteError();\n const { formatMessage } = useIntl();\n const { copy } = useClipboard();\n\n if (error instanceof Error) {\n console.error(error);\n\n const handleClick = async () => {\n await copy(`\n\\`\\`\\`\n${error.stack}\n\\`\\`\\`\n `);\n };\n\n return (\n <Main height=\"100%\">\n <Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <Flex\n gap={7}\n padding={7}\n direction=\"column\"\n width=\"35%\"\n shadow=\"tableShadow\"\n borderColor=\"neutral150\"\n background=\"neutral0\"\n hasRadius\n maxWidth=\"512px\"\n >\n <Flex direction=\"column\" gap={2}>\n <WarningCircle width=\"32px\" height=\"32px\" fill=\"danger600\" />\n <Typography fontSize={4} fontWeight=\"bold\" textAlign=\"center\">\n {formatMessage({\n id: 'app.error',\n defaultMessage: 'Something went wrong',\n })}\n </Typography>\n <Typography variant=\"omega\" textAlign=\"center\">\n {formatMessage(\n {\n id: 'app.error.message',\n defaultMessage: `It seems like there is a bug in your instance, but we've got you covered. Please notify your technical team so they can investigate the source of the problem and report the issue to us by opening a bug report on {link}.`,\n },\n {\n link: (\n <Link\n isExternal\n // hack to get rid of the current endIcon, which should be removable by using `null`.\n endIcon\n href=\"https://github.com/strapi/strapi/issues/new?assignees=&labels=&projects=&template=BUG_REPORT.md\"\n >{`Strapi's GitHub`}</Link>\n ),\n }\n )}\n </Typography>\n </Flex>\n {/* the Alert component needs to make its close button optional as well as the icon. */}\n <Flex gap={4} direction=\"column\" width=\"100%\">\n <StyledAlert onClose={() => {}} width=\"100%\" closeLabel=\"\" variant=\"danger\">\n <ErrorType>{error.message}</ErrorType>\n </StyledAlert>\n <Button onClick={handleClick} variant=\"tertiary\" startIcon={<Duplicate />}>\n {formatMessage({\n id: 'app.error.copy',\n defaultMessage: 'Copy to clipboard',\n })}\n </Button>\n </Flex>\n </Flex>\n </Flex>\n </Main>\n );\n }\n\n throw error;\n};\n\nconst StyledAlert = styled(Alert)`\n & > div:first-child {\n display: none;\n }\n\n & > button {\n display: none;\n }\n`;\n\nconst ErrorType = styled<TypographyComponent>(Typography)`\n word-break: break-all;\n color: ${({ theme }) => theme.colors.danger600};\n`;\n\nexport { ErrorElement };\n"],"names":["ErrorElement","error","useRouteError","formatMessage","useIntl","copy","useClipboard","Error","console","handleClick","stack","_jsx","Main","height","Flex","alignItems","justifyContent","_jsxs","gap","padding","direction","width","shadow","borderColor","background","hasRadius","maxWidth","WarningCircle","fill","Typography","fontSize","fontWeight","textAlign","id","defaultMessage","variant","link","Link","isExternal","endIcon","href","StyledAlert","onClose","closeLabel","ErrorType","message","Button","onClick","startIcon","Duplicate","styled","Alert","theme","colors","danger600"],"mappings":";;;;;;;;;;AAgBA;;;AAGC,UACKA,YAAe,GAAA,IAAA;AACnB,IAAA,MAAMC,KAAQC,GAAAA,4BAAAA,EAAAA;IACd,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;IAC1B,MAAM,EAAEC,IAAI,EAAE,GAAGC,yBAAAA,EAAAA;AAEjB,IAAA,IAAIL,iBAAiBM,KAAO,EAAA;AAC1BC,QAAAA,OAAAA,CAAQP,KAAK,CAACA,KAAAA,CAAAA;AAEd,QAAA,MAAMQ,WAAc,GAAA,UAAA;AAClB,YAAA,MAAMJ,KAAK;;AAEjB,EAAEJ,KAAAA,CAAMS,KAAK;;MAEP,CAAC,CAAA;AACH,SAAA;AAEA,QAAA,qBACEC,cAACC,CAAAA,iBAAAA,EAAAA;YAAKC,MAAO,EAAA,MAAA;AACX,YAAA,QAAA,gBAAAF,cAACG,CAAAA,iBAAAA,EAAAA;gBAAKC,UAAW,EAAA,QAAA;gBAASF,MAAO,EAAA,MAAA;gBAAOG,cAAe,EAAA,QAAA;AACrD,gBAAA,QALine truncated
@@ -0,0 +1,125 @@
import { jsx, jsxs } from 'react/jsx-runtime';
import { Alert, Typography, Main, Flex, Link, Button } from '@strapi/design-system';
import { WarningCircle, Duplicate } from '@strapi/icons';
import { useIntl } from 'react-intl';
import { useRouteError } from 'react-router-dom';
import { styled } from 'styled-components';
import { useClipboard } from '../hooks/useClipboard.mjs';
/**
* @description this stops the app from going white, and instead shows the error message.
* But it could be improved for sure.
*/ const ErrorElement = ()=>{
const error = useRouteError();
const { formatMessage } = useIntl();
const { copy } = useClipboard();
if (error instanceof Error) {
console.error(error);
const handleClick = async ()=>{
await copy(`
\`\`\`
${error.stack}
\`\`\`
`);
};
return /*#__PURE__*/ jsx(Main, {
height: "100%",
children: /*#__PURE__*/ jsx(Flex, {
alignItems: "center",
height: "100%",
justifyContent: "center",
children: /*#__PURE__*/ jsxs(Flex, {
gap: 7,
padding: 7,
direction: "column",
width: "35%",
shadow: "tableShadow",
borderColor: "neutral150",
background: "neutral0",
hasRadius: true,
maxWidth: "512px",
children: [
/*#__PURE__*/ jsxs(Flex, {
direction: "column",
gap: 2,
children: [
/*#__PURE__*/ jsx(WarningCircle, {
width: "32px",
height: "32px",
fill: "danger600"
}),
/*#__PURE__*/ jsx(Typography, {
fontSize: 4,
fontWeight: "bold",
textAlign: "center",
children: formatMessage({
id: 'app.error',
defaultMessage: 'Something went wrong'
})
}),
/*#__PURE__*/ jsx(Typography, {
variant: "omega",
textAlign: "center",
children: formatMessage({
id: 'app.error.message',
defaultMessage: `It seems like there is a bug in your instance, but we've got you covered. Please notify your technical team so they can investigate the source of the problem and report the issue to us by opening a bug report on {link}.`
}, {
link: /*#__PURE__*/ jsx(Link, {
isExternal: true,
// hack to get rid of the current endIcon, which should be removable by using `null`.
endIcon: true,
href: "https://github.com/strapi/strapi/issues/new?assignees=&labels=&projects=&template=BUG_REPORT.md",
children: `Strapi's GitHub`
})
})
})
]
}),
/*#__PURE__*/ jsxs(Flex, {
gap: 4,
direction: "column",
width: "100%",
children: [
/*#__PURE__*/ jsx(StyledAlert, {
onClose: ()=>{},
width: "100%",
closeLabel: "",
variant: "danger",
children: /*#__PURE__*/ jsx(ErrorType, {
children: error.message
})
}),
/*#__PURE__*/ jsx(Button, {
onClick: handleClick,
variant: "tertiary",
startIcon: /*#__PURE__*/ jsx(Duplicate, {}),
children: formatMessage({
id: 'app.error.copy',
defaultMessage: 'Copy to clipboard'
})
})
]
})
]
})
})
});
}
throw error;
};
const StyledAlert = styled(Alert)`
& > div:first-child {
display: none;
}
& > button {
display: none;
}
`;
const ErrorType = styled(Typography)`
word-break: break-all;
color: ${({ theme })=>theme.colors.danger600};
`;
export { ErrorElement };
//# sourceMappingURL=ErrorElement.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"ErrorElement.mjs","sources":["../../../../../admin/src/components/ErrorElement.tsx"],"sourcesContent":["import {\n Alert,\n Button,\n Flex,\n Main,\n Typography,\n Link,\n TypographyComponent,\n} from '@strapi/design-system';\nimport { Duplicate, WarningCircle } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { useRouteError } from 'react-router-dom';\nimport { styled } from 'styled-components';\n\nimport { useClipboard } from '../hooks/useClipboard';\n\n/**\n * @description this stops the app from going white, and instead shows the error message.\n * But it could be improved for sure.\n */\nconst ErrorElement = () => {\n const error = useRouteError();\n const { formatMessage } = useIntl();\n const { copy } = useClipboard();\n\n if (error instanceof Error) {\n console.error(error);\n\n const handleClick = async () => {\n await copy(`\n\\`\\`\\`\n${error.stack}\n\\`\\`\\`\n `);\n };\n\n return (\n <Main height=\"100%\">\n <Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <Flex\n gap={7}\n padding={7}\n direction=\"column\"\n width=\"35%\"\n shadow=\"tableShadow\"\n borderColor=\"neutral150\"\n background=\"neutral0\"\n hasRadius\n maxWidth=\"512px\"\n >\n <Flex direction=\"column\" gap={2}>\n <WarningCircle width=\"32px\" height=\"32px\" fill=\"danger600\" />\n <Typography fontSize={4} fontWeight=\"bold\" textAlign=\"center\">\n {formatMessage({\n id: 'app.error',\n defaultMessage: 'Something went wrong',\n })}\n </Typography>\n <Typography variant=\"omega\" textAlign=\"center\">\n {formatMessage(\n {\n id: 'app.error.message',\n defaultMessage: `It seems like there is a bug in your instance, but we've got you covered. Please notify your technical team so they can investigate the source of the problem and report the issue to us by opening a bug report on {link}.`,\n },\n {\n link: (\n <Link\n isExternal\n // hack to get rid of the current endIcon, which should be removable by using `null`.\n endIcon\n href=\"https://github.com/strapi/strapi/issues/new?assignees=&labels=&projects=&template=BUG_REPORT.md\"\n >{`Strapi's GitHub`}</Link>\n ),\n }\n )}\n </Typography>\n </Flex>\n {/* the Alert component needs to make its close button optional as well as the icon. */}\n <Flex gap={4} direction=\"column\" width=\"100%\">\n <StyledAlert onClose={() => {}} width=\"100%\" closeLabel=\"\" variant=\"danger\">\n <ErrorType>{error.message}</ErrorType>\n </StyledAlert>\n <Button onClick={handleClick} variant=\"tertiary\" startIcon={<Duplicate />}>\n {formatMessage({\n id: 'app.error.copy',\n defaultMessage: 'Copy to clipboard',\n })}\n </Button>\n </Flex>\n </Flex>\n </Flex>\n </Main>\n );\n }\n\n throw error;\n};\n\nconst StyledAlert = styled(Alert)`\n & > div:first-child {\n display: none;\n }\n\n & > button {\n display: none;\n }\n`;\n\nconst ErrorType = styled<TypographyComponent>(Typography)`\n word-break: break-all;\n color: ${({ theme }) => theme.colors.danger600};\n`;\n\nexport { ErrorElement };\n"],"names":["ErrorElement","error","useRouteError","formatMessage","useIntl","copy","useClipboard","Error","console","handleClick","stack","_jsx","Main","height","Flex","alignItems","justifyContent","_jsxs","gap","padding","direction","width","shadow","borderColor","background","hasRadius","maxWidth","WarningCircle","fill","Typography","fontSize","fontWeight","textAlign","id","defaultMessage","variant","link","Link","isExternal","endIcon","href","StyledAlert","onClose","closeLabel","ErrorType","message","Button","onClick","startIcon","Duplicate","styled","Alert","theme","colors","danger600"],"mappings":";;;;;;;;AAgBA;;;AAGC,UACKA,YAAe,GAAA,IAAA;AACnB,IAAA,MAAMC,KAAQC,GAAAA,aAAAA,EAAAA;IACd,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;IAC1B,MAAM,EAAEC,IAAI,EAAE,GAAGC,YAAAA,EAAAA;AAEjB,IAAA,IAAIL,iBAAiBM,KAAO,EAAA;AAC1BC,QAAAA,OAAAA,CAAQP,KAAK,CAACA,KAAAA,CAAAA;AAEd,QAAA,MAAMQ,WAAc,GAAA,UAAA;AAClB,YAAA,MAAMJ,KAAK;;AAEjB,EAAEJ,KAAAA,CAAMS,KAAK;;MAEP,CAAC,CAAA;AACH,SAAA;AAEA,QAAA,qBACEC,GAACC,CAAAA,IAAAA,EAAAA;YAAKC,MAAO,EAAA,MAAA;AACX,YAAA,QAAA,gBAAAF,GAACG,CAAAA,IAAAA,EAAAA;gBAAKC,UAAW,EAAA,QAAA;gBAASF,MAAO,EAAA,MAAA;gBAAOG,cAAe,EAAA,QAAA;AACrD,gBAAA,QAAA,gBALine truncated
@@ -0,0 +1,418 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var reactIntl = require('react-intl');
var filters = require('../constants/filters.js');
var useControllableState = require('../hooks/useControllableState.js');
var useQueryParams = require('../hooks/useQueryParams.js');
var Context = require('./Context.js');
var Form = require('./Form.js');
var Renderer = require('./FormInputs/Renderer.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const [FiltersProvider, useFilters] = Context.createContext('Filters');
const Root = ({ children, disabled = false, onChange, options = [], onOpenChange, open: openProp, defaultOpen, ...restProps })=>{
const handleChange = (data)=>{
if (onChange) {
onChange(data);
}
};
const [open = false, setOpen] = useControllableState.useControllableState({
prop: openProp,
defaultProp: defaultOpen,
onChange: onOpenChange
});
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Popover.Root, {
open: open,
onOpenChange: setOpen,
...restProps,
children: /*#__PURE__*/ jsxRuntime.jsx(FiltersProvider, {
setOpen: setOpen,
disabled: disabled,
onChange: handleChange,
options: options,
children: children
})
});
};
/* -------------------------------------------------------------------------------------------------
* Trigger
* -----------------------------------------------------------------------------------------------*/ const Trigger = /*#__PURE__*/ React__namespace.forwardRef(({ label }, forwardedRef)=>{
const { formatMessage } = reactIntl.useIntl();
const disabled = useFilters('Trigger', ({ disabled })=>disabled);
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Popover.Trigger, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
variant: "tertiary",
ref: forwardedRef,
startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.Filter, {}),
size: "S",
disabled: disabled,
children: label || formatMessage({
id: 'app.utils.filters',
defaultMessage: 'Filters'
})
})
});
});
/* -------------------------------------------------------------------------------------------------
* Popover
* -----------------------------------------------------------------------------------------------*/ const PopoverImpl = ()=>{
const [{ query }, setQuery] = useQueryParams.useQueryParams();
const { formatMessage } = reactIntl.useIntl();
const options = useFilters('Popover', ({ options })=>options);
const onChange = useFilters('Popover', ({ onChange })=>onChange);
const setOpen = useFilters('Popover', ({ setOpen })=>setOpen);
if (options.length === 0) {
return null;
}
const handleSubmit = (data)=>{
const value = filters.FILTERS_WITH_NO_VALUE.includes(data.filter) ? 'true' : encodeURIComponent(data.value ?? '');
if (!value) {
return;
}
if (onChange) {
onChange(data);
}
/**
* There will ALWAYS be an option because we use the options to create the form data.
*/ const fieldOptions = options.find((filter)=>filter.name === data.name);
/**
* If the filter is a relation, we need to nest the filter object,
* we filter based on the mainField of the relation, if there is no mainField, we use the id.
* At the end, we pass the operator & value. This value _could_ look like:
* ```json
* {
* "$eq": "1",
* }
* ```
*/ const operatorValuePairing = {
[data.filter]: value
};
const newFilterQuery = {
...query.filters,
$and: [
...query.filters?.$and ?? [],
{
[data.name]: fieldOptions.type === 'relation' ? {
[fieldOptions.mainField?.name ?? 'id']: operatorValuePairing
} : operatorValuePairing
}
]
};
setQuery({
filters: newFilterQuery,
page: 1
});
setOpen(false);
};
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Popover.Content, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
padding: 3,
children: /*#__PURE__*/ jsxRuntime.jsx(Form.Form, {
method: "POST",
initialValues: {
name: options[0]?.name,
filter: filters.BASE_FILTERS[0].value
},
onSubmit: handleSubmit,
children: ({ values: formValues, modified, isSubmitting })=>{
const filter = options.find((filter)=>filter.name === formValues.name);
const Input = filter?.input || Renderer.InputRenderer;
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
direction: "column",
alignItems: "stretch",
gap: 2,
style: {
minWidth: 184
},
children: [
[
{
['aria-label']: formatMessage({
id: 'app.utils.select-field',
defaultMessage: 'Select field'
}),
name: 'name',
options: options.map((filter)=>({
label: filter.label,
value: filter.name
})),
placholder: formatMessage({
id: 'app.utils.select-field',
defaultMessage: 'Select field'
}),
type: 'enumeration'
},
{
['aria-label']: formatMessage({
id: 'app.utils.select-filter',
defaultMessage: 'Select filter'
}),
name: 'filter',
options: filter?.operators || getFilterList(filter).map((opt)=>({
label: formatMessage(opt.label),
value: opt.value
})),
placeholder: formatMessage({
id: 'app.utils.select-filter',
defaultMessage: 'Select filter'
}),
type: 'enumeration'
}
].map((field)=>/*#__PURE__*/ jsxRuntime.jsx(Renderer.InputRenderer, {
...field
}, field.name)),
filter && formValues.filter && formValues.filter !== '$null' && formValues.filter !== '$notNull' ? /*#__PURE__*/ jsxRuntime.jsx(Input, {
...filter,
label: null,
"aria-label": filter.label,
name: "value",
// @ts-expect-error – if type is `custom` then `Input` will be a custom component.
type: filter.mainField?.type ?? filter.type
}) : null,
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
disabled: !modified || isSubmitting,
size: "L",
variant: "secondary",
startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.Plus, {}),
type: "submit",
fullWidth: true,
children: formatMessage({
id: 'app.utils.add-filter',
defaultMessage: 'Add filter'
})
})
]
});
}
})
})
});
};
/**
* Depending on the selected field find the possible filters to apply
*/ const getFilterList = (filter)=>{
if (!filter) {
return [];
}
const type = filter.mainField?.type ? filter.mainField.type : filter.type;
switch(type){
case 'email':
case 'text':
case 'string':
{
return [
...filters.BASE_FILTERS,
...filters.IS_SENSITIVE_FILTERS,
...filters.CONTAINS_FILTERS,
...filters.STRING_PARSE_FILTERS
];
}
case 'float':
case 'integer':
case 'biginteger':
case 'decimal':
{
return [
...filters.BASE_FILTERS,
...filters.NUMERIC_FILTERS
];
}
case 'time':
case 'date':
{
return [
...filters.BASE_FILTERS,
...filters.NUMERIC_FILTERS,
...filters.CONTAINS_FILTERS
];
}
case 'datetime':
{
return [
...filters.BASE_FILTERS,
...filters.NUMERIC_FILTERS
];
}
case 'enumeration':
{
return filters.BASE_FILTERS;
}
default:
return [
...filters.BASE_FILTERS,
...filters.IS_SENSITIVE_FILTERS
];
}
};
/* -------------------------------------------------------------------------------------------------
* List
* -----------------------------------------------------------------------------------------------*/ const List = ()=>{
const [{ query }, setQuery] = useQueryParams.useQueryParams();
const options = useFilters('List', ({ options })=>options);
const handleClick = (data)=>{
/**
* Check the name, operator and value to see if it already exists in the query
* if it does, remove it.
*/ const nextFilters = (query?.filters?.$and ?? []).filter((filter)=>{
const [attributeName] = Object.keys(filter);
if (attributeName !== data.name) {
return true;
}
const { type, mainField } = options.find(({ name })=>name === attributeName);
if (type === 'relation') {
const filterObj = filter[attributeName][mainField?.name ?? 'id'];
if (typeof filterObj === 'object') {
const [operator] = Object.keys(filterObj);
const value = filterObj[operator];
return !(operator === data.filter && value === data.value);
}
return true;
} else {
const filterObj = filter[attributeName];
const [operator] = Object.keys(filterObj);
const value = filterObj[operator];
return !(operator === data.filter && value === data.value);
}
});
setQuery({
filters: {
$and: nextFilters
},
page: 1
});
};
if (!query?.filters?.$and?.length) {
return null;
}
return /*#__PURE__*/ jsxRuntime.jsx(jsxRuntime.Fragment, {
children: query?.filters?.$and?.map((queryFilter)=>{
const [attributeName] = Object.keys(queryFilter);
const filter = options.find(({ name })=>name === attributeName);
const filterObj = queryFilter[attributeName];
if (!filter || typeof filterObj !== 'object' || filterObj === null) {
return null;
}
if (filter.type === 'relation') {
const modelFilter = filterObj[filter.mainField?.name ?? 'id'];
if (typeof modelFilter === 'object') {
const [operator] = Object.keys(modelFilter);
const value = modelFilter[operator];
return /*#__PURE__*/ jsxRuntime.jsx(AttributeTag, {
...filter,
onClick: handleClick,
operator: operator,
value: value
}, `${attributeName}-${operator}-${value}`);
}
return null;
} else {
const [operator] = Object.keys(filterObj);
const value = filterObj[operator];
/**
* Something has gone wrong here, because the attribute is not a relation
* but we have a nested filter object.
*/ if (typeof value === 'object') {
return null;
}
return /*#__PURE__*/ jsxRuntime.jsx(AttributeTag, {
...filter,
onClick: handleClick,
operator: operator,
value: value
}, `${attributeName}-${operator}-${value}`);
}
})
});
};
const AttributeTag = ({ input, label, mainField, name, onClick, operator, options, value, ...filter })=>{
const { formatMessage, formatDate, formatTime, formatNumber } = reactIntl.useIntl();
const handleClick = ()=>{
onClick({
name,
value,
filter: operator
});
};
const type = mainField?.type ? mainField.type : filter.type;
let formattedValue = value;
switch(type){
case 'date':
formattedValue = formatDate(value, {
dateStyle: 'full'
});
break;
case 'datetime':
formattedValue = formatDate(value, {
dateStyle: 'full',
timeStyle: 'short'
});
break;
case 'time':
const [hour, minute] = value.split(':');
const date = new Date();
date.setHours(Number(hour));
date.setMinutes(Number(minute));
formattedValue = formatTime(date, {
hour: 'numeric',
minute: 'numeric'
});
break;
case 'float':
case 'integer':
case 'biginteger':
case 'decimal':
formattedValue = formatNumber(Number(value));
break;
}
// Handle custom input
if (input && options) {
// If the custom input has an options array, find the option with a customValue matching the query value
const selectedOption = options.find((option)=>{
return (typeof option === 'string' ? option : option.value) === value;
});
formattedValue = selectedOption ? typeof selectedOption === 'string' ? selectedOption : selectedOption.label ?? selectedOption.value : value;
}
const content = `${label} ${formatMessage({
id: `components.FilterOptions.FILTER_TYPES.${operator}`,
defaultMessage: operator
})} ${operator !== '$null' && operator !== '$notNull' ? formattedValue : ''}`;
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Tag, {
padding: 1,
onClick: handleClick,
icon: /*#__PURE__*/ jsxRuntime.jsx(icons.Cross, {}),
children: content
});
};
/* -------------------------------------------------------------------------------------------------
* EXPORTS
* -----------------------------------------------------------------------------------------------*/ const Filters = {
List,
Popover: PopoverImpl,
Root,
Trigger
};
exports.Filters = Filters;
//# sourceMappingURL=Filters.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Filters.js","sources":["../../../../../admin/src/components/Filters.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, Button, Flex, Popover, Tag } from '@strapi/design-system';\nimport { Plus, Filter as FilterIcon, Cross } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport {\n BASE_FILTERS,\n CONTAINS_FILTERS,\n FilterOption,\n IS_SENSITIVE_FILTERS,\n NUMERIC_FILTERS,\n STRING_PARSE_FILTERS,\n FILTERS_WITH_NO_VALUE,\n} from '../constants/filters';\nimport { useControllableState } from '../hooks/useControllableState';\nimport { useQueryParams } from '../hooks/useQueryParams';\n\nimport { createContext } from './Context';\nimport { Form, InputProps } from './Form';\nimport { InputRenderer } from './FormInputs/Renderer';\n\nimport type { Schema } from '@strapi/types';\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FilterFormData {\n name: string;\n filter: string;\n value?: string;\n}\n\ninterface FitlersContextValue {\n disabled: boolean;\n onChange: (data: FilterFormData) => void;\n options: Filters.Filter[];\n setOpen: (open: boolean) => void;\n}\n\nconst [FiltersProvider, useFilters] = createContext<FitlersContextValue>('Filters');\n\ninterface RootProps extends Partial<FitlersContextValue>, Popover.Props {\n children: React.ReactNode;\n}\n\nconst Root = ({\n children,\n disabled = false,\n onChange,\n options = [],\n onOpenChange,\n open: openProp,\n defaultOpen,\n ...restProps\n}: RootProps) => {\n const handleChange = (data: FilterFormData) => {\n if (onChange) {\n onChange(data);\n }\n };\n const [open = false, setOpen] = useControllableState({\n prop: openProp,\n defaultProp: defaultOpen,\n onChange: onOpenChange,\n });\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen} {...restProps}>\n <FiltersProvider\n setOpen={setOpen}\n disabled={disabled}\n onChange={handleChange}\n options={options}\n >\n {children}\n </FiltersProvider>\n </Popover.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Trigger\n * -----------------------------------------------------------------------------------------------*/\n\nconst Trigger = React.forwardRef<HTMLButtonElement, Filters.TriggerProps>(\n ({ label }, forwardedRef) => {\n const { formatMessage } = useIntl();\n const disabled = useFilters('Trigger', ({ disabled }) => disabled);\n\n return (\n <Popover.Trigger>\n <Button\n variant=\"tertiary\"\n ref={forwardedRef}\n startIcon={<FilterIcon />}\n size=\"S\"\n disabled={disabled}\n >\n {label || formatMessage({ id: 'app.utils.filters', defaultMessage: 'Filters' })}\n </Button>\n </Popover.Trigger>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Popover\n * -----------------------------------------------------------------------------------------------*/\n\nconst PopoverImpl = () => {\n const [{ query }, setQuery] = useQueryParams<Filters.Query>();\n const { formatMessage } = useIntl();\n const options = useFilters('Popover', ({ options }) => options);\n const onChange = useFilters('Popover', ({ onChange }) => onChange);\n const setOpen = useFilters('Popover', ({ setOpen }) => setOpen);\n\n if (options.length === 0) {\n return null;\n }\n\n const handleSubmit = (data: FilterFormData) => {\n const value = FILTERS_WITH_NO_VALUE.includes(data.filter)\n ? 'true'\n : encodeURIComponent(data.value ?? '');\n\n if (!value) {\n return;\n }\n\n if (onChange) {\n onChange(data);\n }\n\n /**\n * There will ALWAYS be an option because we use the options to create the form data.\n */\n const fieldOptions = options.find((filter) => filter.name === data.name)!;\n\n /**\n * If the filter is a relation, we need to nest the filter object,\n * we filter based on the mainField of the relation, if there is no mainField, we use the id.\n * At the end, we pass the operator & value. This value _could_ look like:\n * ```json\n * {\n * \"$eq\": \"1\",\n * }\n * ```\n */\n const operatorValuePairing = {\n [data.filter]: value,\n };\n\n const newFilterQuery = {\n ...query.filters,\n $and: [\n ...(query.filters?.$and ?? []),\n {\n [data.name]:\n fieldOptions.type === 'relation'\n ? {\n [fieldOptions.mainField?.name ?? 'id']: operatorValuePairing,\n }\n : operatorValuePairing,\n },\n ],\n };\n\n setQuery({ filters: newFilterQLine truncated
@@ -0,0 +1,397 @@
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import * as React from 'react';
import { Popover, Button, Box, Flex, Tag } from '@strapi/design-system';
import { Filter, Plus, Cross } from '@strapi/icons';
import { useIntl } from 'react-intl';
import { BASE_FILTERS, IS_SENSITIVE_FILTERS, NUMERIC_FILTERS, CONTAINS_FILTERS, STRING_PARSE_FILTERS, FILTERS_WITH_NO_VALUE } from '../constants/filters.mjs';
import { useControllableState } from '../hooks/useControllableState.mjs';
import { useQueryParams } from '../hooks/useQueryParams.mjs';
import { createContext } from './Context.mjs';
import { Form } from './Form.mjs';
import { InputRenderer as MemoizedInputRenderer } from './FormInputs/Renderer.mjs';
const [FiltersProvider, useFilters] = createContext('Filters');
const Root = ({ children, disabled = false, onChange, options = [], onOpenChange, open: openProp, defaultOpen, ...restProps })=>{
const handleChange = (data)=>{
if (onChange) {
onChange(data);
}
};
const [open = false, setOpen] = useControllableState({
prop: openProp,
defaultProp: defaultOpen,
onChange: onOpenChange
});
return /*#__PURE__*/ jsx(Popover.Root, {
open: open,
onOpenChange: setOpen,
...restProps,
children: /*#__PURE__*/ jsx(FiltersProvider, {
setOpen: setOpen,
disabled: disabled,
onChange: handleChange,
options: options,
children: children
})
});
};
/* -------------------------------------------------------------------------------------------------
* Trigger
* -----------------------------------------------------------------------------------------------*/ const Trigger = /*#__PURE__*/ React.forwardRef(({ label }, forwardedRef)=>{
const { formatMessage } = useIntl();
const disabled = useFilters('Trigger', ({ disabled })=>disabled);
return /*#__PURE__*/ jsx(Popover.Trigger, {
children: /*#__PURE__*/ jsx(Button, {
variant: "tertiary",
ref: forwardedRef,
startIcon: /*#__PURE__*/ jsx(Filter, {}),
size: "S",
disabled: disabled,
children: label || formatMessage({
id: 'app.utils.filters',
defaultMessage: 'Filters'
})
})
});
});
/* -------------------------------------------------------------------------------------------------
* Popover
* -----------------------------------------------------------------------------------------------*/ const PopoverImpl = ()=>{
const [{ query }, setQuery] = useQueryParams();
const { formatMessage } = useIntl();
const options = useFilters('Popover', ({ options })=>options);
const onChange = useFilters('Popover', ({ onChange })=>onChange);
const setOpen = useFilters('Popover', ({ setOpen })=>setOpen);
if (options.length === 0) {
return null;
}
const handleSubmit = (data)=>{
const value = FILTERS_WITH_NO_VALUE.includes(data.filter) ? 'true' : encodeURIComponent(data.value ?? '');
if (!value) {
return;
}
if (onChange) {
onChange(data);
}
/**
* There will ALWAYS be an option because we use the options to create the form data.
*/ const fieldOptions = options.find((filter)=>filter.name === data.name);
/**
* If the filter is a relation, we need to nest the filter object,
* we filter based on the mainField of the relation, if there is no mainField, we use the id.
* At the end, we pass the operator & value. This value _could_ look like:
* ```json
* {
* "$eq": "1",
* }
* ```
*/ const operatorValuePairing = {
[data.filter]: value
};
const newFilterQuery = {
...query.filters,
$and: [
...query.filters?.$and ?? [],
{
[data.name]: fieldOptions.type === 'relation' ? {
[fieldOptions.mainField?.name ?? 'id']: operatorValuePairing
} : operatorValuePairing
}
]
};
setQuery({
filters: newFilterQuery,
page: 1
});
setOpen(false);
};
return /*#__PURE__*/ jsx(Popover.Content, {
children: /*#__PURE__*/ jsx(Box, {
padding: 3,
children: /*#__PURE__*/ jsx(Form, {
method: "POST",
initialValues: {
name: options[0]?.name,
filter: BASE_FILTERS[0].value
},
onSubmit: handleSubmit,
children: ({ values: formValues, modified, isSubmitting })=>{
const filter = options.find((filter)=>filter.name === formValues.name);
const Input = filter?.input || MemoizedInputRenderer;
return /*#__PURE__*/ jsxs(Flex, {
direction: "column",
alignItems: "stretch",
gap: 2,
style: {
minWidth: 184
},
children: [
[
{
['aria-label']: formatMessage({
id: 'app.utils.select-field',
defaultMessage: 'Select field'
}),
name: 'name',
options: options.map((filter)=>({
label: filter.label,
value: filter.name
})),
placholder: formatMessage({
id: 'app.utils.select-field',
defaultMessage: 'Select field'
}),
type: 'enumeration'
},
{
['aria-label']: formatMessage({
id: 'app.utils.select-filter',
defaultMessage: 'Select filter'
}),
name: 'filter',
options: filter?.operators || getFilterList(filter).map((opt)=>({
label: formatMessage(opt.label),
value: opt.value
})),
placeholder: formatMessage({
id: 'app.utils.select-filter',
defaultMessage: 'Select filter'
}),
type: 'enumeration'
}
].map((field)=>/*#__PURE__*/ jsx(MemoizedInputRenderer, {
...field
}, field.name)),
filter && formValues.filter && formValues.filter !== '$null' && formValues.filter !== '$notNull' ? /*#__PURE__*/ jsx(Input, {
...filter,
label: null,
"aria-label": filter.label,
name: "value",
// @ts-expect-error – if type is `custom` then `Input` will be a custom component.
type: filter.mainField?.type ?? filter.type
}) : null,
/*#__PURE__*/ jsx(Button, {
disabled: !modified || isSubmitting,
size: "L",
variant: "secondary",
startIcon: /*#__PURE__*/ jsx(Plus, {}),
type: "submit",
fullWidth: true,
children: formatMessage({
id: 'app.utils.add-filter',
defaultMessage: 'Add filter'
})
})
]
});
}
})
})
});
};
/**
* Depending on the selected field find the possible filters to apply
*/ const getFilterList = (filter)=>{
if (!filter) {
return [];
}
const type = filter.mainField?.type ? filter.mainField.type : filter.type;
switch(type){
case 'email':
case 'text':
case 'string':
{
return [
...BASE_FILTERS,
...IS_SENSITIVE_FILTERS,
...CONTAINS_FILTERS,
...STRING_PARSE_FILTERS
];
}
case 'float':
case 'integer':
case 'biginteger':
case 'decimal':
{
return [
...BASE_FILTERS,
...NUMERIC_FILTERS
];
}
case 'time':
case 'date':
{
return [
...BASE_FILTERS,
...NUMERIC_FILTERS,
...CONTAINS_FILTERS
];
}
case 'datetime':
{
return [
...BASE_FILTERS,
...NUMERIC_FILTERS
];
}
case 'enumeration':
{
return BASE_FILTERS;
}
default:
return [
...BASE_FILTERS,
...IS_SENSITIVE_FILTERS
];
}
};
/* -------------------------------------------------------------------------------------------------
* List
* -----------------------------------------------------------------------------------------------*/ const List = ()=>{
const [{ query }, setQuery] = useQueryParams();
const options = useFilters('List', ({ options })=>options);
const handleClick = (data)=>{
/**
* Check the name, operator and value to see if it already exists in the query
* if it does, remove it.
*/ const nextFilters = (query?.filters?.$and ?? []).filter((filter)=>{
const [attributeName] = Object.keys(filter);
if (attributeName !== data.name) {
return true;
}
const { type, mainField } = options.find(({ name })=>name === attributeName);
if (type === 'relation') {
const filterObj = filter[attributeName][mainField?.name ?? 'id'];
if (typeof filterObj === 'object') {
const [operator] = Object.keys(filterObj);
const value = filterObj[operator];
return !(operator === data.filter && value === data.value);
}
return true;
} else {
const filterObj = filter[attributeName];
const [operator] = Object.keys(filterObj);
const value = filterObj[operator];
return !(operator === data.filter && value === data.value);
}
});
setQuery({
filters: {
$and: nextFilters
},
page: 1
});
};
if (!query?.filters?.$and?.length) {
return null;
}
return /*#__PURE__*/ jsx(Fragment, {
children: query?.filters?.$and?.map((queryFilter)=>{
const [attributeName] = Object.keys(queryFilter);
const filter = options.find(({ name })=>name === attributeName);
const filterObj = queryFilter[attributeName];
if (!filter || typeof filterObj !== 'object' || filterObj === null) {
return null;
}
if (filter.type === 'relation') {
const modelFilter = filterObj[filter.mainField?.name ?? 'id'];
if (typeof modelFilter === 'object') {
const [operator] = Object.keys(modelFilter);
const value = modelFilter[operator];
return /*#__PURE__*/ jsx(AttributeTag, {
...filter,
onClick: handleClick,
operator: operator,
value: value
}, `${attributeName}-${operator}-${value}`);
}
return null;
} else {
const [operator] = Object.keys(filterObj);
const value = filterObj[operator];
/**
* Something has gone wrong here, because the attribute is not a relation
* but we have a nested filter object.
*/ if (typeof value === 'object') {
return null;
}
return /*#__PURE__*/ jsx(AttributeTag, {
...filter,
onClick: handleClick,
operator: operator,
value: value
}, `${attributeName}-${operator}-${value}`);
}
})
});
};
const AttributeTag = ({ input, label, mainField, name, onClick, operator, options, value, ...filter })=>{
const { formatMessage, formatDate, formatTime, formatNumber } = useIntl();
const handleClick = ()=>{
onClick({
name,
value,
filter: operator
});
};
const type = mainField?.type ? mainField.type : filter.type;
let formattedValue = value;
switch(type){
case 'date':
formattedValue = formatDate(value, {
dateStyle: 'full'
});
break;
case 'datetime':
formattedValue = formatDate(value, {
dateStyle: 'full',
timeStyle: 'short'
});
break;
case 'time':
const [hour, minute] = value.split(':');
const date = new Date();
date.setHours(Number(hour));
date.setMinutes(Number(minute));
formattedValue = formatTime(date, {
hour: 'numeric',
minute: 'numeric'
});
break;
case 'float':
case 'integer':
case 'biginteger':
case 'decimal':
formattedValue = formatNumber(Number(value));
break;
}
// Handle custom input
if (input && options) {
// If the custom input has an options array, find the option with a customValue matching the query value
const selectedOption = options.find((option)=>{
return (typeof option === 'string' ? option : option.value) === value;
});
formattedValue = selectedOption ? typeof selectedOption === 'string' ? selectedOption : selectedOption.label ?? selectedOption.value : value;
}
const content = `${label} ${formatMessage({
id: `components.FilterOptions.FILTER_TYPES.${operator}`,
defaultMessage: operator
})} ${operator !== '$null' && operator !== '$notNull' ? formattedValue : ''}`;
return /*#__PURE__*/ jsx(Tag, {
padding: 1,
onClick: handleClick,
icon: /*#__PURE__*/ jsx(Cross, {}),
children: content
});
};
/* -------------------------------------------------------------------------------------------------
* EXPORTS
* -----------------------------------------------------------------------------------------------*/ const Filters = {
List,
Popover: PopoverImpl,
Root,
Trigger
};
export { Filters };
//# sourceMappingURL=Filters.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"Filters.mjs","sources":["../../../../../admin/src/components/Filters.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, Button, Flex, Popover, Tag } from '@strapi/design-system';\nimport { Plus, Filter as FilterIcon, Cross } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport {\n BASE_FILTERS,\n CONTAINS_FILTERS,\n FilterOption,\n IS_SENSITIVE_FILTERS,\n NUMERIC_FILTERS,\n STRING_PARSE_FILTERS,\n FILTERS_WITH_NO_VALUE,\n} from '../constants/filters';\nimport { useControllableState } from '../hooks/useControllableState';\nimport { useQueryParams } from '../hooks/useQueryParams';\n\nimport { createContext } from './Context';\nimport { Form, InputProps } from './Form';\nimport { InputRenderer } from './FormInputs/Renderer';\n\nimport type { Schema } from '@strapi/types';\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FilterFormData {\n name: string;\n filter: string;\n value?: string;\n}\n\ninterface FitlersContextValue {\n disabled: boolean;\n onChange: (data: FilterFormData) => void;\n options: Filters.Filter[];\n setOpen: (open: boolean) => void;\n}\n\nconst [FiltersProvider, useFilters] = createContext<FitlersContextValue>('Filters');\n\ninterface RootProps extends Partial<FitlersContextValue>, Popover.Props {\n children: React.ReactNode;\n}\n\nconst Root = ({\n children,\n disabled = false,\n onChange,\n options = [],\n onOpenChange,\n open: openProp,\n defaultOpen,\n ...restProps\n}: RootProps) => {\n const handleChange = (data: FilterFormData) => {\n if (onChange) {\n onChange(data);\n }\n };\n const [open = false, setOpen] = useControllableState({\n prop: openProp,\n defaultProp: defaultOpen,\n onChange: onOpenChange,\n });\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen} {...restProps}>\n <FiltersProvider\n setOpen={setOpen}\n disabled={disabled}\n onChange={handleChange}\n options={options}\n >\n {children}\n </FiltersProvider>\n </Popover.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Trigger\n * -----------------------------------------------------------------------------------------------*/\n\nconst Trigger = React.forwardRef<HTMLButtonElement, Filters.TriggerProps>(\n ({ label }, forwardedRef) => {\n const { formatMessage } = useIntl();\n const disabled = useFilters('Trigger', ({ disabled }) => disabled);\n\n return (\n <Popover.Trigger>\n <Button\n variant=\"tertiary\"\n ref={forwardedRef}\n startIcon={<FilterIcon />}\n size=\"S\"\n disabled={disabled}\n >\n {label || formatMessage({ id: 'app.utils.filters', defaultMessage: 'Filters' })}\n </Button>\n </Popover.Trigger>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Popover\n * -----------------------------------------------------------------------------------------------*/\n\nconst PopoverImpl = () => {\n const [{ query }, setQuery] = useQueryParams<Filters.Query>();\n const { formatMessage } = useIntl();\n const options = useFilters('Popover', ({ options }) => options);\n const onChange = useFilters('Popover', ({ onChange }) => onChange);\n const setOpen = useFilters('Popover', ({ setOpen }) => setOpen);\n\n if (options.length === 0) {\n return null;\n }\n\n const handleSubmit = (data: FilterFormData) => {\n const value = FILTERS_WITH_NO_VALUE.includes(data.filter)\n ? 'true'\n : encodeURIComponent(data.value ?? '');\n\n if (!value) {\n return;\n }\n\n if (onChange) {\n onChange(data);\n }\n\n /**\n * There will ALWAYS be an option because we use the options to create the form data.\n */\n const fieldOptions = options.find((filter) => filter.name === data.name)!;\n\n /**\n * If the filter is a relation, we need to nest the filter object,\n * we filter based on the mainField of the relation, if there is no mainField, we use the id.\n * At the end, we pass the operator & value. This value _could_ look like:\n * ```json\n * {\n * \"$eq\": \"1\",\n * }\n * ```\n */\n const operatorValuePairing = {\n [data.filter]: value,\n };\n\n const newFilterQuery = {\n ...query.filters,\n $and: [\n ...(query.filters?.$and ?? []),\n {\n [data.name]:\n fieldOptions.type === 'relation'\n ? {\n [fieldOptions.mainField?.name ?? 'id']: operatorValuePairing,\n }\n : operatorValuePairing,\n },\n ],\n };\n\n setQuery({ filters: newFilterLine truncated
@@ -0,0 +1,565 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var fractionalIndexing = require('fractional-indexing');
var immer = require('immer');
var isEqual = require('lodash/isEqual');
var reactIntl = require('react-intl');
var reactRouterDom = require('react-router-dom');
var objects = require('../utils/objects.js');
var Context = require('./Context.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
/**
* @internal
* @description We use this just to warn people that they're using the useForm
* methods outside of a Form component, but we don't want to throw an error
* because otherwise the DocumentActions list cannot be rendered in our list-view.
*/ const ERR_MSG = 'The Form Component has not been initialised, ensure you are using this hook within a Form component';
const [FormProvider, useForm] = Context.createContext('Form', {
disabled: false,
errors: {},
initialValues: {},
isSubmitting: false,
modified: false,
addFieldRow: ()=>{
throw new Error(ERR_MSG);
},
moveFieldRow: ()=>{
throw new Error(ERR_MSG);
},
onChange: ()=>{
throw new Error(ERR_MSG);
},
removeFieldRow: ()=>{
throw new Error(ERR_MSG);
},
resetForm: ()=>{
throw new Error(ERR_MSG);
},
setErrors: ()=>{
throw new Error(ERR_MSG);
},
setValues: ()=>{
throw new Error(ERR_MSG);
},
setSubmitting: ()=>{
throw new Error(ERR_MSG);
},
validate: async ()=>{
throw new Error(ERR_MSG);
},
values: {}
});
/**
* @alpha
* @description A form component that handles form state, validation and submission.
* It can additionally handle nested fields and arrays. To access the data you can either
* use the generic useForm hook or the useField hook when providing the name of your field.
*/ const Form = /*#__PURE__*/ React__namespace.forwardRef(({ disabled = false, method, onSubmit, initialErrors, ...props }, ref)=>{
const formRef = React__namespace.useRef(null);
const initialValues = React__namespace.useRef(props.initialValues ?? {});
const [state, dispatch] = React__namespace.useReducer(reducer, {
errors: initialErrors ?? {},
isSubmitting: false,
values: props.initialValues ?? {}
});
React__namespace.useEffect(()=>{
/**
* ONLY update the initialValues if the prop has changed.
*/ if (!isEqual(initialValues.current, props.initialValues)) {
initialValues.current = props.initialValues ?? {};
dispatch({
type: 'SET_INITIAL_VALUES',
payload: props.initialValues ?? {}
});
}
}, [
props.initialValues
]);
const setErrors = React__namespace.useCallback((errors)=>{
dispatch({
type: 'SET_ERRORS',
payload: errors
});
}, []);
const setValues = React__namespace.useCallback((values)=>{
dispatch({
type: 'SET_VALUES',
payload: values
});
}, []);
React__namespace.useEffect(()=>{
if (Object.keys(state.errors).length === 0) return;
/**
* Small timeout to ensure the form has been
* rendered before we try to focus on the first
*/ const ref = setTimeout(()=>{
const [firstError] = formRef.current.querySelectorAll('[data-strapi-field-error]');
if (firstError) {
const errorId = firstError.getAttribute('id');
const formElementInError = formRef.current.querySelector(`[aria-describedby="${errorId}"]`);
if (formElementInError && formElementInError instanceof HTMLElement) {
formElementInError.focus();
}
}
});
return ()=>clearTimeout(ref);
}, [
state.errors
]);
/**
* Uses the provided validation schema
*/ const validate = React__namespace.useCallback(async (shouldSetErrors = true, options = {})=>{
setErrors({});
if (!props.validationSchema && !props.validate) {
return {
data: state.values
};
}
try {
let data;
if (props.validationSchema) {
data = await props.validationSchema.validate(state.values, {
abortEarly: false
});
} else if (props.validate) {
data = await props.validate(state.values, options);
} else {
throw new Error('No validation schema or validate function provided');
}
return {
data
};
} catch (err) {
if (isErrorYupValidationError(err)) {
const errors = getYupValidationErrors(err);
if (shouldSetErrors) {
setErrors(errors);
}
return {
errors
};
} else {
// We throw any other errors
if (process.env.NODE_ENV !== 'production') {
console.warn(`Warning: An unhandled error was caught during validation in <Form validationSchema />`, err);
}
throw err;
}
}
}, [
props,
setErrors,
state.values
]);
const handleSubmit = async (e)=>{
e.stopPropagation();
e.preventDefault();
if (!onSubmit) {
return;
}
dispatch({
type: 'SUBMIT_ATTEMPT'
});
try {
const { data, errors } = await validate();
if (errors) {
setErrors(errors);
throw new Error('Submission failed');
}
await onSubmit(data, {
setErrors,
setValues,
resetForm
});
dispatch({
type: 'SUBMIT_SUCCESS'
});
} catch (err) {
dispatch({
type: 'SUBMIT_FAILURE'
});
if (err instanceof Error && err.message === 'Submission failed') {
return;
}
}
};
const modified = React__namespace.useMemo(()=>!isEqual(initialValues.current, state.values), [
state.values
]);
const handleChange = designSystem.useCallbackRef((eventOrPath, v)=>{
if (typeof eventOrPath === 'string') {
dispatch({
type: 'SET_FIELD_VALUE',
payload: {
field: eventOrPath,
value: v
}
});
return;
}
const target = eventOrPath.target || eventOrPath.currentTarget;
const { type, name, id, value, options, multiple } = target;
const field = name || id;
if (!field && process.env.NODE_ENV !== 'production') {
console.warn(`\`onChange\` was called with an event, but you forgot to pass a \`name\` or \`id'\` attribute to your input. The field to update cannot be determined`);
}
/**
* Because we handle any field from this function, we run through a series
* of checks to understand how to use the value.
*/ let val;
if (/number|range/.test(type)) {
const parsed = parseFloat(value);
// If the value isn't a number for whatever reason, don't let it through because that will break the API.
val = isNaN(parsed) ? '' : parsed;
} else if (/checkbox/.test(type)) {
// Get & invert the current value of the checkbox.
val = !objects.getIn(state.values, field);
} else if (options && multiple) {
// This will handle native select elements incl. ones with mulitple options.
val = Array.from(options).filter((el)=>el.selected).map((el)=>el.value);
} else {
// NOTE: reset value to null so it failes required checks.
// The API only considers a required field invalid if the value is null|undefined, to differentiate from min 1
if (value === '') {
val = null;
} else {
val = value;
}
}
if (field) {
dispatch({
type: 'SET_FIELD_VALUE',
payload: {
field,
value: val
}
});
}
});
const addFieldRow = React__namespace.useCallback((field, value, addAtIndex)=>{
dispatch({
type: 'ADD_FIELD_ROW',
payload: {
field,
value,
addAtIndex
}
});
}, []);
const removeFieldRow = React__namespace.useCallback((field, removeAtIndex)=>{
dispatch({
type: 'REMOVE_FIELD_ROW',
payload: {
field,
removeAtIndex
}
});
}, []);
const moveFieldRow = React__namespace.useCallback((field, fromIndex, toIndex)=>{
dispatch({
type: 'MOVE_FIELD_ROW',
payload: {
field,
fromIndex,
toIndex
}
});
}, []);
const resetForm = React__namespace.useCallback(()=>{
dispatch({
type: 'RESET_FORM',
payload: {
errors: {},
isSubmitting: false,
values: initialValues.current
}
});
}, []);
const setSubmitting = React__namespace.useCallback((isSubmitting)=>{
dispatch({
type: 'SET_ISSUBMITTING',
payload: isSubmitting
});
}, []);
const composedRefs = designSystem.useComposedRefs(formRef, ref);
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
tag: "form",
ref: composedRefs,
method: method,
noValidate: true,
onSubmit: handleSubmit,
width: props.width,
height: props.height,
children: /*#__PURE__*/ jsxRuntime.jsx(FormProvider, {
disabled: disabled,
onChange: handleChange,
initialValues: initialValues.current,
modified: modified,
addFieldRow: addFieldRow,
moveFieldRow: moveFieldRow,
removeFieldRow: removeFieldRow,
resetForm: resetForm,
setErrors: setErrors,
setValues: setValues,
setSubmitting: setSubmitting,
validate: validate,
...state,
children: typeof props.children === 'function' ? props.children({
modified,
disabled,
onChange: handleChange,
...state,
setErrors,
resetForm
}) : props.children
})
});
}); // we've cast this because we need the generic to infer the type of the form values.
/**
* @internal
* @description Checks if the error is a Yup validation error.
*/ const isErrorYupValidationError = (err)=>typeof err === 'object' && err !== null && 'name' in err && typeof err.name === 'string' && err.name === 'ValidationError';
/* -------------------------------------------------------------------------------------------------
* getYupValidationErrors
* -----------------------------------------------------------------------------------------------*/ /**
* @description handy utility to convert a yup validation error into a form
* error object. To be used elsewhere.
*/ const getYupValidationErrors = (err)=>{
let errors = {};
if (err.inner) {
if (err.inner.length === 0) {
return objects.setIn(errors, err.path, err.message);
}
for (const error of err.inner){
if (!objects.getIn(errors, error.path)) {
errors = objects.setIn(errors, error.path, error.message);
}
}
}
return errors;
};
const reducer = (state, action)=>immer.produce(state, (draft)=>{
switch(action.type){
case 'SET_INITIAL_VALUES':
// @ts-expect-error – TODO: figure out why this fails ts.
draft.values = action.payload;
break;
case 'SET_VALUES':
// @ts-expect-error – TODO: figure out why this fails ts.
draft.values = action.payload;
break;
case 'SUBMIT_ATTEMPT':
draft.isSubmitting = true;
break;
case 'SUBMIT_FAILURE':
draft.isSubmitting = false;
break;
case 'SUBMIT_SUCCESS':
draft.isSubmitting = false;
break;
case 'SET_FIELD_VALUE':
draft.values = objects.setIn(state.values, action.payload.field, action.payload.value);
break;
case 'ADD_FIELD_ROW':
{
/**
* TODO: add check for if the field is an array?
*/ const currentField = objects.getIn(state.values, action.payload.field, []);
let position = action.payload.addAtIndex;
if (position === undefined) {
position = currentField.length;
} else if (position < 0) {
position = 0;
}
const [key] = fractionalIndexing.generateNKeysBetween(position > 0 ? currentField.at(position - 1)?.__temp_key__ : null, currentField.at(position)?.__temp_key__, 1);
draft.values = objects.setIn(state.values, action.payload.field, currentField.toSpliced(position, 0, {
...action.payload.value,
__temp_key__: key
}));
break;
}
case 'MOVE_FIELD_ROW':
{
const { field, fromIndex, toIndex } = action.payload;
/**
* TODO: add check for if the field is an array?
*/ const currentField = [
...objects.getIn(state.values, field, [])
];
const currentRow = currentField[fromIndex];
const startKey = fromIndex > toIndex ? currentField[toIndex - 1]?.__temp_key__ : currentField[toIndex]?.__temp_key__;
const endKey = fromIndex > toIndex ? currentField[toIndex]?.__temp_key__ : currentField[toIndex + 1]?.__temp_key__;
const [newKey] = fractionalIndexing.generateNKeysBetween(startKey, endKey, 1);
currentField.splice(fromIndex, 1);
currentField.splice(toIndex, 0, {
...currentRow,
__temp_key__: newKey
});
draft.values = objects.setIn(state.values, field, currentField);
break;
}
case 'REMOVE_FIELD_ROW':
{
/**
* TODO: add check for if the field is an array?
*/ const currentField = objects.getIn(state.values, action.payload.field, []);
let position = action.payload.removeAtIndex;
if (position === undefined) {
position = currentField.length - 1;
} else if (position < 0) {
position = 0;
}
/**
* filter out empty values from the array, the setIn function only deletes the value
* when we pass undefined as opposed to "removing" it from said array.
*/ const newValue = objects.setIn(currentField, position.toString(), undefined).filter((val)=>val);
draft.values = objects.setIn(state.values, action.payload.field, newValue.length > 0 ? newValue : []);
break;
}
case 'SET_ERRORS':
if (!isEqual(state.errors, action.payload)) {
// @ts-expect-error – TODO: figure out why this fails a TS check.
draft.errors = action.payload;
}
break;
case 'SET_ISSUBMITTING':
draft.isSubmitting = action.payload;
break;
case 'RESET_FORM':
// @ts-expect-error – TODO: figure out why this fails ts.
draft.values = action.payload.values;
// @ts-expect-error – TODO: figure out why this fails ts.
draft.errors = action.payload.errors;
draft.isSubmitting = action.payload.isSubmitting;
break;
}
});
function useField(path) {
const { formatMessage } = reactIntl.useIntl();
const initialValue = useForm('useField', (state)=>objects.getIn(state.initialValues, path));
const value = useForm('useField', (state)=>objects.getIn(state.values, path));
const handleChange = useForm('useField', (state)=>state.onChange);
const rawError = useForm('useField', (state)=>objects.getIn(state.errors, path));
const error = useForm('useField', (state)=>{
const error = objects.getIn(state.errors, path);
if (isErrorMessageDescriptor(error)) {
const { values, ...message } = error;
return formatMessage(message, values);
}
return error;
});
return {
initialValue,
/**
* Errors can be a string, or a MessageDescriptor, so we need to handle both cases.
* If it's anything else, we don't return it.
*/ rawError,
error: isErrorMessageDescriptor(error) ? formatMessage({
id: error.id,
defaultMessage: error.defaultMessage
}, error.values) : typeof error === 'string' ? error : undefined,
onChange: handleChange,
value: value
};
}
const isErrorMessageDescriptor = (object)=>{
return typeof object === 'object' && object !== null && !Array.isArray(object) && 'id' in object && 'defaultMessage' in object;
};
/* -------------------------------------------------------------------------------------------------
* Blocker
* -----------------------------------------------------------------------------------------------*/ const Blocker = ({ onProceed = ()=>{}, onCancel = ()=>{} })=>{
const { formatMessage } = reactIntl.useIntl();
const modified = useForm('Blocker', (state)=>state.modified);
const isSubmitting = useForm('Blocker', (state)=>state.isSubmitting);
const blocker = reactRouterDom.useBlocker(({ currentLocation, nextLocation })=>{
return !isSubmitting && modified && (currentLocation.pathname !== nextLocation.pathname || currentLocation.search !== nextLocation.search);
});
if (blocker.state === 'blocked') {
const handleCancel = (isOpen)=>{
if (!isOpen) {
onCancel();
blocker.reset();
}
};
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Root, {
open: true,
onOpenChange: handleCancel,
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Dialog.Content, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Header, {
children: formatMessage({
id: 'app.components.ConfirmDialog.title',
defaultMessage: 'Confirmation'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Body, {
icon: /*#__PURE__*/ jsxRuntime.jsx(icons.WarningCircle, {
width: "24px",
height: "24px",
fill: "danger600"
}),
children: formatMessage({
id: 'global.prompt.unsaved',
defaultMessage: 'You have unsaved changes, are you sure you want to leave?'
})
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Dialog.Footer, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Cancel, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
variant: "tertiary",
children: formatMessage({
id: 'app.components.Button.cancel',
defaultMessage: 'Cancel'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
onClick: ()=>{
onProceed();
blocker.proceed();
},
variant: "danger",
children: formatMessage({
id: 'app.components.Button.confirm',
defaultMessage: 'Confirm'
})
})
]
})
]
})
});
}
return null;
};
exports.Blocker = Blocker;
exports.Form = Form;
exports.getYupValidationErrors = getYupValidationErrors;
exports.useField = useField;
exports.useForm = useForm;
//# sourceMappingURL=Form.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Form.js","sources":["../../../../../admin/src/components/Form.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Box,\n type BoxProps,\n Button,\n Dialog,\n useCallbackRef,\n useComposedRefs,\n} from '@strapi/design-system';\nimport { WarningCircle } from '@strapi/icons';\nimport { generateNKeysBetween } from 'fractional-indexing';\nimport { produce } from 'immer';\nimport isEqual from 'lodash/isEqual';\nimport { useIntl, type MessageDescriptor, type PrimitiveType } from 'react-intl';\nimport { useBlocker } from 'react-router-dom';\n\nimport { getIn, setIn } from '../utils/objects';\n\nimport { createContext } from './Context';\n\nimport type {\n InputProps as InputPropsImpl,\n StringProps,\n EnumerationProps,\n} from './FormInputs/types';\nimport type * as Yup from 'yup';\n\n/* -------------------------------------------------------------------------------------------------\n * FormContext\n * -----------------------------------------------------------------------------------------------*/\ntype InputProps = InputPropsImpl | StringProps | EnumerationProps;\n\ninterface TranslationMessage extends MessageDescriptor {\n values?: Record<string, PrimitiveType>;\n}\n\ninterface FormValues {\n [field: string]: any;\n}\n\ninterface FormContextValue<TFormValues extends FormValues = FormValues>\n extends FormState<TFormValues> {\n disabled: boolean;\n initialValues: TFormValues;\n modified: boolean;\n /**\n * The default behaviour is to add the row to the end of the array, if you want to add it to a\n * specific index you can pass the index.\n */\n addFieldRow: (field: string, value: any, addAtIndex?: number) => void;\n moveFieldRow: (field: string, fromIndex: number, toIndex: number) => void;\n onChange: (eventOrPath: React.ChangeEvent<any> | string, value?: any) => void;\n /*\n * The default behaviour is to remove the last row, if you want to remove a specific index you can\n * pass the index.\n */\n removeFieldRow: (field: string, removeAtIndex?: number) => void;\n resetForm: () => void;\n setErrors: (errors: FormErrors<TFormValues>) => void;\n setSubmitting: (isSubmitting: boolean) => void;\n setValues: (values: TFormValues) => void;\n validate: (\n shouldSetErrors?: boolean,\n options?: Record<string, string>\n ) => Promise<\n { data: TFormValues; errors?: never } | { data?: never; errors: FormErrors<TFormValues> }\n >;\n}\n\n/**\n * @internal\n * @description We use this just to warn people that they're using the useForm\n * methods outside of a Form component, but we don't want to throw an error\n * because otherwise the DocumentActions list cannot be rendered in our list-view.\n */\nconst ERR_MSG =\n 'The Form Component has not been initialised, ensure you are using this hook within a Form component';\n\nconst [FormProvider, useForm] = createContext<FormContextValue>('Form', {\n disabled: false,\n errors: {},\n initialValues: {},\n isSubmitting: false,\n modified: false,\n addFieldRow: () => {\n throw new Error(ERR_MSG);\n },\n moveFieldRow: () => {\n throw new Error(ERR_MSG);\n },\n onChange: () => {\n throw new Error(ERR_MSG);\n },\n removeFieldRow: () => {\n throw new Error(ERR_MSG);\n },\n resetForm: () => {\n throw new Error(ERR_MSG);\n },\n setErrors: () => {\n throw new Error(ERR_MSG);\n },\n setValues: () => {\n throw new Error(ERR_MSG);\n },\n setSubmitting: () => {\n throw new Error(ERR_MSG);\n },\n validate: async () => {\n throw new Error(ERR_MSG);\n },\n values: {},\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Form\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FormHelpers<TFormValues extends FormValues = FormValues>\n extends Pick<FormContextValue<TFormValues>, 'setErrors' | 'setValues' | 'resetForm'> {}\n\ninterface FormProps<TFormValues extends FormValues = FormValues>\n extends Partial<Pick<FormContextValue<TFormValues>, 'disabled' | 'initialValues'>>,\n Pick<BoxProps, 'width' | 'height'> {\n children:\n | React.ReactNode\n | ((\n props: Pick<\n FormContextValue<TFormValues>,\n | 'disabled'\n | 'errors'\n | 'isSubmitting'\n | 'modified'\n | 'values'\n | 'resetForm'\n | 'onChange'\n | 'setErrors'\n >\n ) => React.ReactNode);\n method: 'POST' | 'PUT';\n onSubmit?: (values: TFormValues, helpers: FormHelpers<TFormValues>) => Promise<void> | void;\n // TODO: type the return value for a validation schema func from Yup.\n validationSchema?: Yup.AnySchema;\n initialErrors?: FormErrors<TFormValues>;\n // NOTE: we don't know what return type it can be here\n validate?: (values: TFormValues, options: Record<string, string>) => Promise<any>;\n}\n\n/**\n * @alpha\n * @description A form component that handles formLine truncated
@@ -0,0 +1,540 @@
import { jsx, jsxs } from 'react/jsx-runtime';
import * as React from 'react';
import { useCallbackRef, useComposedRefs, Box, Dialog, Button } from '@strapi/design-system';
import { WarningCircle } from '@strapi/icons';
import { generateNKeysBetween } from 'fractional-indexing';
import { produce } from 'immer';
import isEqual from 'lodash/isEqual';
import { useIntl } from 'react-intl';
import { useBlocker } from 'react-router-dom';
import { getIn, setIn } from '../utils/objects.mjs';
import { createContext } from './Context.mjs';
/**
* @internal
* @description We use this just to warn people that they're using the useForm
* methods outside of a Form component, but we don't want to throw an error
* because otherwise the DocumentActions list cannot be rendered in our list-view.
*/ const ERR_MSG = 'The Form Component has not been initialised, ensure you are using this hook within a Form component';
const [FormProvider, useForm] = createContext('Form', {
disabled: false,
errors: {},
initialValues: {},
isSubmitting: false,
modified: false,
addFieldRow: ()=>{
throw new Error(ERR_MSG);
},
moveFieldRow: ()=>{
throw new Error(ERR_MSG);
},
onChange: ()=>{
throw new Error(ERR_MSG);
},
removeFieldRow: ()=>{
throw new Error(ERR_MSG);
},
resetForm: ()=>{
throw new Error(ERR_MSG);
},
setErrors: ()=>{
throw new Error(ERR_MSG);
},
setValues: ()=>{
throw new Error(ERR_MSG);
},
setSubmitting: ()=>{
throw new Error(ERR_MSG);
},
validate: async ()=>{
throw new Error(ERR_MSG);
},
values: {}
});
/**
* @alpha
* @description A form component that handles form state, validation and submission.
* It can additionally handle nested fields and arrays. To access the data you can either
* use the generic useForm hook or the useField hook when providing the name of your field.
*/ const Form = /*#__PURE__*/ React.forwardRef(({ disabled = false, method, onSubmit, initialErrors, ...props }, ref)=>{
const formRef = React.useRef(null);
const initialValues = React.useRef(props.initialValues ?? {});
const [state, dispatch] = React.useReducer(reducer, {
errors: initialErrors ?? {},
isSubmitting: false,
values: props.initialValues ?? {}
});
React.useEffect(()=>{
/**
* ONLY update the initialValues if the prop has changed.
*/ if (!isEqual(initialValues.current, props.initialValues)) {
initialValues.current = props.initialValues ?? {};
dispatch({
type: 'SET_INITIAL_VALUES',
payload: props.initialValues ?? {}
});
}
}, [
props.initialValues
]);
const setErrors = React.useCallback((errors)=>{
dispatch({
type: 'SET_ERRORS',
payload: errors
});
}, []);
const setValues = React.useCallback((values)=>{
dispatch({
type: 'SET_VALUES',
payload: values
});
}, []);
React.useEffect(()=>{
if (Object.keys(state.errors).length === 0) return;
/**
* Small timeout to ensure the form has been
* rendered before we try to focus on the first
*/ const ref = setTimeout(()=>{
const [firstError] = formRef.current.querySelectorAll('[data-strapi-field-error]');
if (firstError) {
const errorId = firstError.getAttribute('id');
const formElementInError = formRef.current.querySelector(`[aria-describedby="${errorId}"]`);
if (formElementInError && formElementInError instanceof HTMLElement) {
formElementInError.focus();
}
}
});
return ()=>clearTimeout(ref);
}, [
state.errors
]);
/**
* Uses the provided validation schema
*/ const validate = React.useCallback(async (shouldSetErrors = true, options = {})=>{
setErrors({});
if (!props.validationSchema && !props.validate) {
return {
data: state.values
};
}
try {
let data;
if (props.validationSchema) {
data = await props.validationSchema.validate(state.values, {
abortEarly: false
});
} else if (props.validate) {
data = await props.validate(state.values, options);
} else {
throw new Error('No validation schema or validate function provided');
}
return {
data
};
} catch (err) {
if (isErrorYupValidationError(err)) {
const errors = getYupValidationErrors(err);
if (shouldSetErrors) {
setErrors(errors);
}
return {
errors
};
} else {
// We throw any other errors
if (process.env.NODE_ENV !== 'production') {
console.warn(`Warning: An unhandled error was caught during validation in <Form validationSchema />`, err);
}
throw err;
}
}
}, [
props,
setErrors,
state.values
]);
const handleSubmit = async (e)=>{
e.stopPropagation();
e.preventDefault();
if (!onSubmit) {
return;
}
dispatch({
type: 'SUBMIT_ATTEMPT'
});
try {
const { data, errors } = await validate();
if (errors) {
setErrors(errors);
throw new Error('Submission failed');
}
await onSubmit(data, {
setErrors,
setValues,
resetForm
});
dispatch({
type: 'SUBMIT_SUCCESS'
});
} catch (err) {
dispatch({
type: 'SUBMIT_FAILURE'
});
if (err instanceof Error && err.message === 'Submission failed') {
return;
}
}
};
const modified = React.useMemo(()=>!isEqual(initialValues.current, state.values), [
state.values
]);
const handleChange = useCallbackRef((eventOrPath, v)=>{
if (typeof eventOrPath === 'string') {
dispatch({
type: 'SET_FIELD_VALUE',
payload: {
field: eventOrPath,
value: v
}
});
return;
}
const target = eventOrPath.target || eventOrPath.currentTarget;
const { type, name, id, value, options, multiple } = target;
const field = name || id;
if (!field && process.env.NODE_ENV !== 'production') {
console.warn(`\`onChange\` was called with an event, but you forgot to pass a \`name\` or \`id'\` attribute to your input. The field to update cannot be determined`);
}
/**
* Because we handle any field from this function, we run through a series
* of checks to understand how to use the value.
*/ let val;
if (/number|range/.test(type)) {
const parsed = parseFloat(value);
// If the value isn't a number for whatever reason, don't let it through because that will break the API.
val = isNaN(parsed) ? '' : parsed;
} else if (/checkbox/.test(type)) {
// Get & invert the current value of the checkbox.
val = !getIn(state.values, field);
} else if (options && multiple) {
// This will handle native select elements incl. ones with mulitple options.
val = Array.from(options).filter((el)=>el.selected).map((el)=>el.value);
} else {
// NOTE: reset value to null so it failes required checks.
// The API only considers a required field invalid if the value is null|undefined, to differentiate from min 1
if (value === '') {
val = null;
} else {
val = value;
}
}
if (field) {
dispatch({
type: 'SET_FIELD_VALUE',
payload: {
field,
value: val
}
});
}
});
const addFieldRow = React.useCallback((field, value, addAtIndex)=>{
dispatch({
type: 'ADD_FIELD_ROW',
payload: {
field,
value,
addAtIndex
}
});
}, []);
const removeFieldRow = React.useCallback((field, removeAtIndex)=>{
dispatch({
type: 'REMOVE_FIELD_ROW',
payload: {
field,
removeAtIndex
}
});
}, []);
const moveFieldRow = React.useCallback((field, fromIndex, toIndex)=>{
dispatch({
type: 'MOVE_FIELD_ROW',
payload: {
field,
fromIndex,
toIndex
}
});
}, []);
const resetForm = React.useCallback(()=>{
dispatch({
type: 'RESET_FORM',
payload: {
errors: {},
isSubmitting: false,
values: initialValues.current
}
});
}, []);
const setSubmitting = React.useCallback((isSubmitting)=>{
dispatch({
type: 'SET_ISSUBMITTING',
payload: isSubmitting
});
}, []);
const composedRefs = useComposedRefs(formRef, ref);
return /*#__PURE__*/ jsx(Box, {
tag: "form",
ref: composedRefs,
method: method,
noValidate: true,
onSubmit: handleSubmit,
width: props.width,
height: props.height,
children: /*#__PURE__*/ jsx(FormProvider, {
disabled: disabled,
onChange: handleChange,
initialValues: initialValues.current,
modified: modified,
addFieldRow: addFieldRow,
moveFieldRow: moveFieldRow,
removeFieldRow: removeFieldRow,
resetForm: resetForm,
setErrors: setErrors,
setValues: setValues,
setSubmitting: setSubmitting,
validate: validate,
...state,
children: typeof props.children === 'function' ? props.children({
modified,
disabled,
onChange: handleChange,
...state,
setErrors,
resetForm
}) : props.children
})
});
}); // we've cast this because we need the generic to infer the type of the form values.
/**
* @internal
* @description Checks if the error is a Yup validation error.
*/ const isErrorYupValidationError = (err)=>typeof err === 'object' && err !== null && 'name' in err && typeof err.name === 'string' && err.name === 'ValidationError';
/* -------------------------------------------------------------------------------------------------
* getYupValidationErrors
* -----------------------------------------------------------------------------------------------*/ /**
* @description handy utility to convert a yup validation error into a form
* error object. To be used elsewhere.
*/ const getYupValidationErrors = (err)=>{
let errors = {};
if (err.inner) {
if (err.inner.length === 0) {
return setIn(errors, err.path, err.message);
}
for (const error of err.inner){
if (!getIn(errors, error.path)) {
errors = setIn(errors, error.path, error.message);
}
}
}
return errors;
};
const reducer = (state, action)=>produce(state, (draft)=>{
switch(action.type){
case 'SET_INITIAL_VALUES':
// @ts-expect-error – TODO: figure out why this fails ts.
draft.values = action.payload;
break;
case 'SET_VALUES':
// @ts-expect-error – TODO: figure out why this fails ts.
draft.values = action.payload;
break;
case 'SUBMIT_ATTEMPT':
draft.isSubmitting = true;
break;
case 'SUBMIT_FAILURE':
draft.isSubmitting = false;
break;
case 'SUBMIT_SUCCESS':
draft.isSubmitting = false;
break;
case 'SET_FIELD_VALUE':
draft.values = setIn(state.values, action.payload.field, action.payload.value);
break;
case 'ADD_FIELD_ROW':
{
/**
* TODO: add check for if the field is an array?
*/ const currentField = getIn(state.values, action.payload.field, []);
let position = action.payload.addAtIndex;
if (position === undefined) {
position = currentField.length;
} else if (position < 0) {
position = 0;
}
const [key] = generateNKeysBetween(position > 0 ? currentField.at(position - 1)?.__temp_key__ : null, currentField.at(position)?.__temp_key__, 1);
draft.values = setIn(state.values, action.payload.field, currentField.toSpliced(position, 0, {
...action.payload.value,
__temp_key__: key
}));
break;
}
case 'MOVE_FIELD_ROW':
{
const { field, fromIndex, toIndex } = action.payload;
/**
* TODO: add check for if the field is an array?
*/ const currentField = [
...getIn(state.values, field, [])
];
const currentRow = currentField[fromIndex];
const startKey = fromIndex > toIndex ? currentField[toIndex - 1]?.__temp_key__ : currentField[toIndex]?.__temp_key__;
const endKey = fromIndex > toIndex ? currentField[toIndex]?.__temp_key__ : currentField[toIndex + 1]?.__temp_key__;
const [newKey] = generateNKeysBetween(startKey, endKey, 1);
currentField.splice(fromIndex, 1);
currentField.splice(toIndex, 0, {
...currentRow,
__temp_key__: newKey
});
draft.values = setIn(state.values, field, currentField);
break;
}
case 'REMOVE_FIELD_ROW':
{
/**
* TODO: add check for if the field is an array?
*/ const currentField = getIn(state.values, action.payload.field, []);
let position = action.payload.removeAtIndex;
if (position === undefined) {
position = currentField.length - 1;
} else if (position < 0) {
position = 0;
}
/**
* filter out empty values from the array, the setIn function only deletes the value
* when we pass undefined as opposed to "removing" it from said array.
*/ const newValue = setIn(currentField, position.toString(), undefined).filter((val)=>val);
draft.values = setIn(state.values, action.payload.field, newValue.length > 0 ? newValue : []);
break;
}
case 'SET_ERRORS':
if (!isEqual(state.errors, action.payload)) {
// @ts-expect-error – TODO: figure out why this fails a TS check.
draft.errors = action.payload;
}
break;
case 'SET_ISSUBMITTING':
draft.isSubmitting = action.payload;
break;
case 'RESET_FORM':
// @ts-expect-error – TODO: figure out why this fails ts.
draft.values = action.payload.values;
// @ts-expect-error – TODO: figure out why this fails ts.
draft.errors = action.payload.errors;
draft.isSubmitting = action.payload.isSubmitting;
break;
}
});
function useField(path) {
const { formatMessage } = useIntl();
const initialValue = useForm('useField', (state)=>getIn(state.initialValues, path));
const value = useForm('useField', (state)=>getIn(state.values, path));
const handleChange = useForm('useField', (state)=>state.onChange);
const rawError = useForm('useField', (state)=>getIn(state.errors, path));
const error = useForm('useField', (state)=>{
const error = getIn(state.errors, path);
if (isErrorMessageDescriptor(error)) {
const { values, ...message } = error;
return formatMessage(message, values);
}
return error;
});
return {
initialValue,
/**
* Errors can be a string, or a MessageDescriptor, so we need to handle both cases.
* If it's anything else, we don't return it.
*/ rawError,
error: isErrorMessageDescriptor(error) ? formatMessage({
id: error.id,
defaultMessage: error.defaultMessage
}, error.values) : typeof error === 'string' ? error : undefined,
onChange: handleChange,
value: value
};
}
const isErrorMessageDescriptor = (object)=>{
return typeof object === 'object' && object !== null && !Array.isArray(object) && 'id' in object && 'defaultMessage' in object;
};
/* -------------------------------------------------------------------------------------------------
* Blocker
* -----------------------------------------------------------------------------------------------*/ const Blocker = ({ onProceed = ()=>{}, onCancel = ()=>{} })=>{
const { formatMessage } = useIntl();
const modified = useForm('Blocker', (state)=>state.modified);
const isSubmitting = useForm('Blocker', (state)=>state.isSubmitting);
const blocker = useBlocker(({ currentLocation, nextLocation })=>{
return !isSubmitting && modified && (currentLocation.pathname !== nextLocation.pathname || currentLocation.search !== nextLocation.search);
});
if (blocker.state === 'blocked') {
const handleCancel = (isOpen)=>{
if (!isOpen) {
onCancel();
blocker.reset();
}
};
return /*#__PURE__*/ jsx(Dialog.Root, {
open: true,
onOpenChange: handleCancel,
children: /*#__PURE__*/ jsxs(Dialog.Content, {
children: [
/*#__PURE__*/ jsx(Dialog.Header, {
children: formatMessage({
id: 'app.components.ConfirmDialog.title',
defaultMessage: 'Confirmation'
})
}),
/*#__PURE__*/ jsx(Dialog.Body, {
icon: /*#__PURE__*/ jsx(WarningCircle, {
width: "24px",
height: "24px",
fill: "danger600"
}),
children: formatMessage({
id: 'global.prompt.unsaved',
defaultMessage: 'You have unsaved changes, are you sure you want to leave?'
})
}),
/*#__PURE__*/ jsxs(Dialog.Footer, {
children: [
/*#__PURE__*/ jsx(Dialog.Cancel, {
children: /*#__PURE__*/ jsx(Button, {
variant: "tertiary",
children: formatMessage({
id: 'app.components.Button.cancel',
defaultMessage: 'Cancel'
})
})
}),
/*#__PURE__*/ jsx(Button, {
onClick: ()=>{
onProceed();
blocker.proceed();
},
variant: "danger",
children: formatMessage({
id: 'app.components.Button.confirm',
defaultMessage: 'Confirm'
})
})
]
})
]
})
});
}
return null;
};
export { Blocker, Form, getYupValidationErrors, useField, useForm };
//# sourceMappingURL=Form.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"Form.mjs","sources":["../../../../../admin/src/components/Form.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Box,\n type BoxProps,\n Button,\n Dialog,\n useCallbackRef,\n useComposedRefs,\n} from '@strapi/design-system';\nimport { WarningCircle } from '@strapi/icons';\nimport { generateNKeysBetween } from 'fractional-indexing';\nimport { produce } from 'immer';\nimport isEqual from 'lodash/isEqual';\nimport { useIntl, type MessageDescriptor, type PrimitiveType } from 'react-intl';\nimport { useBlocker } from 'react-router-dom';\n\nimport { getIn, setIn } from '../utils/objects';\n\nimport { createContext } from './Context';\n\nimport type {\n InputProps as InputPropsImpl,\n StringProps,\n EnumerationProps,\n} from './FormInputs/types';\nimport type * as Yup from 'yup';\n\n/* -------------------------------------------------------------------------------------------------\n * FormContext\n * -----------------------------------------------------------------------------------------------*/\ntype InputProps = InputPropsImpl | StringProps | EnumerationProps;\n\ninterface TranslationMessage extends MessageDescriptor {\n values?: Record<string, PrimitiveType>;\n}\n\ninterface FormValues {\n [field: string]: any;\n}\n\ninterface FormContextValue<TFormValues extends FormValues = FormValues>\n extends FormState<TFormValues> {\n disabled: boolean;\n initialValues: TFormValues;\n modified: boolean;\n /**\n * The default behaviour is to add the row to the end of the array, if you want to add it to a\n * specific index you can pass the index.\n */\n addFieldRow: (field: string, value: any, addAtIndex?: number) => void;\n moveFieldRow: (field: string, fromIndex: number, toIndex: number) => void;\n onChange: (eventOrPath: React.ChangeEvent<any> | string, value?: any) => void;\n /*\n * The default behaviour is to remove the last row, if you want to remove a specific index you can\n * pass the index.\n */\n removeFieldRow: (field: string, removeAtIndex?: number) => void;\n resetForm: () => void;\n setErrors: (errors: FormErrors<TFormValues>) => void;\n setSubmitting: (isSubmitting: boolean) => void;\n setValues: (values: TFormValues) => void;\n validate: (\n shouldSetErrors?: boolean,\n options?: Record<string, string>\n ) => Promise<\n { data: TFormValues; errors?: never } | { data?: never; errors: FormErrors<TFormValues> }\n >;\n}\n\n/**\n * @internal\n * @description We use this just to warn people that they're using the useForm\n * methods outside of a Form component, but we don't want to throw an error\n * because otherwise the DocumentActions list cannot be rendered in our list-view.\n */\nconst ERR_MSG =\n 'The Form Component has not been initialised, ensure you are using this hook within a Form component';\n\nconst [FormProvider, useForm] = createContext<FormContextValue>('Form', {\n disabled: false,\n errors: {},\n initialValues: {},\n isSubmitting: false,\n modified: false,\n addFieldRow: () => {\n throw new Error(ERR_MSG);\n },\n moveFieldRow: () => {\n throw new Error(ERR_MSG);\n },\n onChange: () => {\n throw new Error(ERR_MSG);\n },\n removeFieldRow: () => {\n throw new Error(ERR_MSG);\n },\n resetForm: () => {\n throw new Error(ERR_MSG);\n },\n setErrors: () => {\n throw new Error(ERR_MSG);\n },\n setValues: () => {\n throw new Error(ERR_MSG);\n },\n setSubmitting: () => {\n throw new Error(ERR_MSG);\n },\n validate: async () => {\n throw new Error(ERR_MSG);\n },\n values: {},\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Form\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FormHelpers<TFormValues extends FormValues = FormValues>\n extends Pick<FormContextValue<TFormValues>, 'setErrors' | 'setValues' | 'resetForm'> {}\n\ninterface FormProps<TFormValues extends FormValues = FormValues>\n extends Partial<Pick<FormContextValue<TFormValues>, 'disabled' | 'initialValues'>>,\n Pick<BoxProps, 'width' | 'height'> {\n children:\n | React.ReactNode\n | ((\n props: Pick<\n FormContextValue<TFormValues>,\n | 'disabled'\n | 'errors'\n | 'isSubmitting'\n | 'modified'\n | 'values'\n | 'resetForm'\n | 'onChange'\n | 'setErrors'\n >\n ) => React.ReactNode);\n method: 'POST' | 'PUT';\n onSubmit?: (values: TFormValues, helpers: FormHelpers<TFormValues>) => Promise<void> | void;\n // TODO: type the return value for a validation schema func from Yup.\n validationSchema?: Yup.AnySchema;\n initialErrors?: FormErrors<TFormValues>;\n // NOTE: we don't know what return type it can be here\n validate?: (values: TFormValues, options: Record<string, string>) => Promise<any>;\n}\n\n/**\n * @alpha\n * @description A form component that handles forLine truncated
@@ -0,0 +1,48 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var reactIntl = require('react-intl');
var useFocusInputField = require('../../hooks/useFocusInputField.js');
var Form = require('../Form.js');
const BooleanInput = /*#__PURE__*/ React.forwardRef(({ name, required, label, hint, labelAction, ...props }, ref)=>{
const { formatMessage } = reactIntl.useIntl();
const field = Form.useField(name);
const fieldRef = useFocusInputField.useFocusInputField(name);
const composedRefs = designSystem.useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
maxWidth: "320px",
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Toggle, {
ref: composedRefs,
checked: field.value === null ? null : field.value || false,
offLabel: formatMessage({
id: 'app.components.ToggleCheckbox.off-label',
defaultMessage: 'False'
}),
onLabel: formatMessage({
id: 'app.components.ToggleCheckbox.on-label',
defaultMessage: 'True'
}),
onChange: field.onChange,
...props
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Hint, {}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
});
});
const MemoizedBooleanInput = /*#__PURE__*/ React.memo(BooleanInput);
exports.BooleanInput = MemoizedBooleanInput;
//# sourceMappingURL=Boolean.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Boolean.js","sources":["../../../../../../admin/src/components/FormInputs/Boolean.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { Toggle, useComposedRefs, Field } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst BooleanInput = forwardRef<HTMLInputElement, InputProps>(\n ({ name, required, label, hint, labelAction, ...props }, ref) => {\n const { formatMessage } = useIntl();\n const field = useField<boolean | null>(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required} maxWidth=\"320px\">\n <Field.Label action={labelAction}>{label}</Field.Label>\n <Toggle\n ref={composedRefs}\n checked={field.value === null ? null : field.value || false}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.off-label',\n defaultMessage: 'False',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.on-label',\n defaultMessage: 'True',\n })}\n onChange={field.onChange}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedBooleanInput = memo(BooleanInput);\n\nexport { MemoizedBooleanInput as BooleanInput };\n"],"names":["BooleanInput","forwardRef","name","required","label","hint","labelAction","props","ref","formatMessage","useIntl","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","maxWidth","_jsx","Label","action","Toggle","checked","value","offLabel","id","defaultMessage","onLabel","onChange","Hint","Error","MemoizedBooleanInput","memo"],"mappings":";;;;;;;;;AAUA,MAAMA,6BAAeC,gBACnB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;IACvD,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAMC,QAAQC,aAAyBV,CAAAA,IAAAA,CAAAA;AACvC,IAAA,MAAMW,WAAWC,qCAAqCZ,CAAAA,IAAAA,CAAAA;IAEtD,MAAMa,YAAAA,GAAeC,6BAAgBR,GAAKK,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,eAAA,CAACC,mBAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAElB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;QAAUkB,QAAS,EAAA,OAAA;;AACnF,0BAAAC,cAAA,CAACJ,mBAAMK,KAAK,EAAA;gBAACC,MAAQlB,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCkB,cAACG,CAAAA,mBAAAA,EAAAA;gBACCjB,GAAKO,EAAAA,YAAAA;AACLW,gBAAAA,OAAAA,EAASf,MAAMgB,KAAK,KAAK,OAAO,IAAOhB,GAAAA,KAAAA,CAAMgB,KAAK,IAAI,KAAA;AACtDC,gBAAAA,QAAAA,EAAUnB,aAAc,CAAA;oBACtBoB,EAAI,EAAA,yCAAA;oBACJC,cAAgB,EAAA;AAClB,iBAAA,CAAA;AACAC,gBAAAA,OAAAA,EAAStB,aAAc,CAAA;oBACrBoB,EAAI,EAAA,wCAAA;oBACJC,cAAgB,EAAA;AAClB,iBAAA,CAAA;AACAE,gBAAAA,QAAAA,EAAUrB,MAAMqB,QAAQ;AACvB,gBAAA,GAAGzB;;AAEN,0BAAAe,cAAA,CAACJ,mBAAMe,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAX,cAAA,CAACJ,mBAAMgB,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,qCAAuBC,UAAKpC,CAAAA,YAAAA;;;;"}
@@ -0,0 +1,46 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import { memo, forwardRef } from 'react';
import { useComposedRefs, Field, Toggle } from '@strapi/design-system';
import { useIntl } from 'react-intl';
import { useFocusInputField } from '../../hooks/useFocusInputField.mjs';
import { useField } from '../Form.mjs';
const BooleanInput = /*#__PURE__*/ forwardRef(({ name, required, label, hint, labelAction, ...props }, ref)=>{
const { formatMessage } = useIntl();
const field = useField(name);
const fieldRef = useFocusInputField(name);
const composedRefs = useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxs(Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
maxWidth: "320px",
children: [
/*#__PURE__*/ jsx(Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsx(Toggle, {
ref: composedRefs,
checked: field.value === null ? null : field.value || false,
offLabel: formatMessage({
id: 'app.components.ToggleCheckbox.off-label',
defaultMessage: 'False'
}),
onLabel: formatMessage({
id: 'app.components.ToggleCheckbox.on-label',
defaultMessage: 'True'
}),
onChange: field.onChange,
...props
}),
/*#__PURE__*/ jsx(Field.Hint, {}),
/*#__PURE__*/ jsx(Field.Error, {})
]
});
});
const MemoizedBooleanInput = /*#__PURE__*/ memo(BooleanInput);
export { MemoizedBooleanInput as BooleanInput };
//# sourceMappingURL=Boolean.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"Boolean.mjs","sources":["../../../../../../admin/src/components/FormInputs/Boolean.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { Toggle, useComposedRefs, Field } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst BooleanInput = forwardRef<HTMLInputElement, InputProps>(\n ({ name, required, label, hint, labelAction, ...props }, ref) => {\n const { formatMessage } = useIntl();\n const field = useField<boolean | null>(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required} maxWidth=\"320px\">\n <Field.Label action={labelAction}>{label}</Field.Label>\n <Toggle\n ref={composedRefs}\n checked={field.value === null ? null : field.value || false}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.off-label',\n defaultMessage: 'False',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.on-label',\n defaultMessage: 'True',\n })}\n onChange={field.onChange}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedBooleanInput = memo(BooleanInput);\n\nexport { MemoizedBooleanInput as BooleanInput };\n"],"names":["BooleanInput","forwardRef","name","required","label","hint","labelAction","props","ref","formatMessage","useIntl","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","maxWidth","_jsx","Label","action","Toggle","checked","value","offLabel","id","defaultMessage","onLabel","onChange","Hint","Error","MemoizedBooleanInput","memo"],"mappings":";;;;;;;AAUA,MAAMA,6BAAeC,UACnB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;IACvD,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAC1B,IAAA,MAAMC,QAAQC,QAAyBV,CAAAA,IAAAA,CAAAA;AACvC,IAAA,MAAMW,WAAWC,kBAAqCZ,CAAAA,IAAAA,CAAAA;IAEtD,MAAMa,YAAAA,GAAeC,gBAAgBR,GAAKK,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,IAAA,CAACC,MAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAElB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;QAAUkB,QAAS,EAAA,OAAA;;AACnF,0BAAAC,GAAA,CAACJ,MAAMK,KAAK,EAAA;gBAACC,MAAQlB,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCkB,GAACG,CAAAA,MAAAA,EAAAA;gBACCjB,GAAKO,EAAAA,YAAAA;AACLW,gBAAAA,OAAAA,EAASf,MAAMgB,KAAK,KAAK,OAAO,IAAOhB,GAAAA,KAAAA,CAAMgB,KAAK,IAAI,KAAA;AACtDC,gBAAAA,QAAAA,EAAUnB,aAAc,CAAA;oBACtBoB,EAAI,EAAA,yCAAA;oBACJC,cAAgB,EAAA;AAClB,iBAAA,CAAA;AACAC,gBAAAA,OAAAA,EAAStB,aAAc,CAAA;oBACrBoB,EAAI,EAAA,wCAAA;oBACJC,cAAgB,EAAA;AAClB,iBAAA,CAAA;AACAE,gBAAAA,QAAAA,EAAUrB,MAAMqB,QAAQ;AACvB,gBAAA,GAAGzB;;AAEN,0BAAAe,GAAA,CAACJ,MAAMe,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAX,GAAA,CAACJ,MAAMgB,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,qCAAuBC,IAAKpC,CAAAA,YAAAA;;;;"}
@@ -0,0 +1,34 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var useFocusInputField = require('../../hooks/useFocusInputField.js');
var Form = require('../Form.js');
const CheckboxInput = /*#__PURE__*/ React.forwardRef(({ name, required, label, hint, type: _type, ...props }, ref)=>{
const field = Form.useField(name);
const fieldRef = useFocusInputField.useFocusInputField(name);
const composedRefs = designSystem.useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Checkbox, {
onCheckedChange: (checked)=>field.onChange(name, !!checked),
ref: composedRefs,
checked: field.value,
...props,
children: label || props['aria-label']
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Hint, {}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
});
});
const MemoizedCheckboxInput = /*#__PURE__*/ React.memo(CheckboxInput);
exports.CheckboxInput = MemoizedCheckboxInput;
//# sourceMappingURL=Checkbox.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Checkbox.js","sources":["../../../../../../admin/src/components/FormInputs/Checkbox.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { Checkbox, useComposedRefs, Field } from '@strapi/design-system';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst CheckboxInput = forwardRef<HTMLButtonElement, InputProps>(\n ({ name, required, label, hint, type: _type, ...props }, ref) => {\n const field = useField<boolean>(name);\n const fieldRef = useFocusInputField<HTMLButtonElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Checkbox\n onCheckedChange={(checked) => field.onChange(name, !!checked)}\n ref={composedRefs}\n checked={field.value}\n {...props}\n >\n {label || props['aria-label']}\n </Checkbox>\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedCheckboxInput = memo(CheckboxInput);\n\nexport { MemoizedCheckboxInput as CheckboxInput };\n"],"names":["CheckboxInput","forwardRef","name","required","label","hint","type","_type","props","ref","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Checkbox","onCheckedChange","checked","onChange","value","Hint","Error","MemoizedCheckboxInput","memo"],"mappings":";;;;;;;;AASA,MAAMA,8BAAgBC,gBACpB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,IAAAA,EAAMC,KAAK,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;AACvD,IAAA,MAAMC,QAAQC,aAAkBT,CAAAA,IAAAA,CAAAA;AAChC,IAAA,MAAMU,WAAWC,qCAAsCX,CAAAA,IAAAA,CAAAA;IAEvD,MAAMY,YAAAA,GAAeC,6BAAgBN,GAAKG,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,eAAA,CAACC,mBAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAEjB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;0BAChEiB,cAACC,CAAAA,qBAAAA,EAAAA;AACCC,gBAAAA,eAAAA,EAAiB,CAACC,OAAYb,GAAAA,KAAAA,CAAMc,QAAQ,CAACtB,IAAAA,EAAM,CAAC,CAACqB,OAAAA,CAAAA;gBACrDd,GAAKK,EAAAA,YAAAA;AACLS,gBAAAA,OAAAA,EAASb,MAAMe,KAAK;AACnB,gBAAA,GAAGjB,KAAK;0BAERJ,KAASI,IAAAA,KAAK,CAAC,YAAa;;AAE/B,0BAAAY,cAAA,CAACH,mBAAMS,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAN,cAAA,CAACH,mBAAMU,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,sCAAwBC,UAAK7B,CAAAA,aAAAA;;;;"}
@@ -0,0 +1,32 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import { memo, forwardRef } from 'react';
import { useComposedRefs, Field, Checkbox } from '@strapi/design-system';
import { useFocusInputField } from '../../hooks/useFocusInputField.mjs';
import { useField } from '../Form.mjs';
const CheckboxInput = /*#__PURE__*/ forwardRef(({ name, required, label, hint, type: _type, ...props }, ref)=>{
const field = useField(name);
const fieldRef = useFocusInputField(name);
const composedRefs = useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxs(Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsx(Checkbox, {
onCheckedChange: (checked)=>field.onChange(name, !!checked),
ref: composedRefs,
checked: field.value,
...props,
children: label || props['aria-label']
}),
/*#__PURE__*/ jsx(Field.Hint, {}),
/*#__PURE__*/ jsx(Field.Error, {})
]
});
});
const MemoizedCheckboxInput = /*#__PURE__*/ memo(CheckboxInput);
export { MemoizedCheckboxInput as CheckboxInput };
//# sourceMappingURL=Checkbox.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"Checkbox.mjs","sources":["../../../../../../admin/src/components/FormInputs/Checkbox.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { Checkbox, useComposedRefs, Field } from '@strapi/design-system';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst CheckboxInput = forwardRef<HTMLButtonElement, InputProps>(\n ({ name, required, label, hint, type: _type, ...props }, ref) => {\n const field = useField<boolean>(name);\n const fieldRef = useFocusInputField<HTMLButtonElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Checkbox\n onCheckedChange={(checked) => field.onChange(name, !!checked)}\n ref={composedRefs}\n checked={field.value}\n {...props}\n >\n {label || props['aria-label']}\n </Checkbox>\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedCheckboxInput = memo(CheckboxInput);\n\nexport { MemoizedCheckboxInput as CheckboxInput };\n"],"names":["CheckboxInput","forwardRef","name","required","label","hint","type","_type","props","ref","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Checkbox","onCheckedChange","checked","onChange","value","Hint","Error","MemoizedCheckboxInput","memo"],"mappings":";;;;;;AASA,MAAMA,8BAAgBC,UACpB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,IAAAA,EAAMC,KAAK,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;AACvD,IAAA,MAAMC,QAAQC,QAAkBT,CAAAA,IAAAA,CAAAA;AAChC,IAAA,MAAMU,WAAWC,kBAAsCX,CAAAA,IAAAA,CAAAA;IAEvD,MAAMY,YAAAA,GAAeC,gBAAgBN,GAAKG,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,IAAA,CAACC,MAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAEjB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;0BAChEiB,GAACC,CAAAA,QAAAA,EAAAA;AACCC,gBAAAA,eAAAA,EAAiB,CAACC,OAAYb,GAAAA,KAAAA,CAAMc,QAAQ,CAACtB,IAAAA,EAAM,CAAC,CAACqB,OAAAA,CAAAA;gBACrDd,GAAKK,EAAAA,YAAAA;AACLS,gBAAAA,OAAAA,EAASb,MAAMe,KAAK;AACnB,gBAAA,GAAGjB,KAAK;0BAERJ,KAASI,IAAAA,KAAK,CAAC,YAAa;;AAE/B,0BAAAY,GAAA,CAACH,MAAMS,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAN,GAAA,CAACH,MAAMU,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,sCAAwBC,IAAK7B,CAAAA,aAAAA;;;;"}
@@ -0,0 +1,92 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var reactIntl = require('react-intl');
var useFocusInputField = require('../../hooks/useFocusInputField.js');
var Form = require('../Form.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const DateInput = /*#__PURE__*/ React__namespace.forwardRef(({ name, required, label, hint, labelAction, type: _type, ...props }, ref)=>{
const { formatMessage } = reactIntl.useIntl();
const field = Form.useField(name);
const fieldRef = useFocusInputField.useFocusInputField(name);
const composedRefs = designSystem.useComposedRefs(ref, fieldRef);
const [lastValidDate, setLastValidDate] = React__namespace.useState(null);
const value = typeof field.value === 'string' ? new Date(field.value) : field.value;
const handleDateChange = (date)=>{
if (!date) {
field.onChange(name, null);
setLastValidDate(null);
return;
}
// Convert to UTC midnight
const utcDate = toUTCMidnight(date);
// Save as ISO string in UTC format
field.onChange(name, utcDate.toISOString());
setLastValidDate(utcDate);
};
// Render the DatePicker with UTC date
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.DatePicker, {
ref: composedRefs,
clearLabel: formatMessage({
id: 'clearLabel',
defaultMessage: 'Clear'
}),
onChange: handleDateChange,
onClear: ()=>{
field.onChange(name, null);
setLastValidDate(null);
return;
},
onBlur: ()=>{
// When the input is blurred, revert to the last valid date if the current value is invalid
if (field.value && !value) {
field.onChange(name, lastValidDate?.toISOString() ?? null);
}
},
value: value,
...props
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Hint, {}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
});
});
// Ensure the conversion to UTC midnight
const toUTCMidnight = (date)=>{
return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
};
const MemoizedDateInput = /*#__PURE__*/ React__namespace.memo(DateInput);
exports.DateInput = MemoizedDateInput;
//# sourceMappingURL=Date.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Date.js","sources":["../../../../../../admin/src/components/FormInputs/Date.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { DatePicker, useComposedRefs, Field } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst DateInput = React.forwardRef<HTMLInputElement, InputProps>(\n ({ name, required, label, hint, labelAction, type: _type, ...props }, ref) => {\n const { formatMessage } = useIntl();\n const field = useField(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n const composedRefs = useComposedRefs(ref, fieldRef);\n const [lastValidDate, setLastValidDate] = React.useState<Date | null>(null);\n\n const value = typeof field.value === 'string' ? new Date(field.value) : field.value;\n\n const handleDateChange = (date: Date | undefined) => {\n if (!date) {\n field.onChange(name, null);\n setLastValidDate(null);\n return;\n }\n\n // Convert to UTC midnight\n const utcDate = toUTCMidnight(date);\n // Save as ISO string in UTC format\n field.onChange(name, utcDate.toISOString());\n setLastValidDate(utcDate);\n };\n\n // Render the DatePicker with UTC date\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <DatePicker\n ref={composedRefs}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n onChange={handleDateChange}\n onClear={() => {\n field.onChange(name, null);\n setLastValidDate(null);\n return;\n }}\n onBlur={() => {\n // When the input is blurred, revert to the last valid date if the current value is invalid\n if (field.value && !value) {\n field.onChange(name, lastValidDate?.toISOString() ?? null);\n }\n }}\n value={value}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\n// Ensure the conversion to UTC midnight\nconst toUTCMidnight = (date: Date) => {\n return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));\n};\n\nconst MemoizedDateInput = React.memo(DateInput);\n\nexport { MemoizedDateInput as DateInput };\n"],"names":["DateInput","React","forwardRef","name","required","label","hint","labelAction","type","_type","props","ref","formatMessage","useIntl","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","lastValidDate","setLastValidDate","useState","value","Date","handleDateChange","date","onChange","utcDate","toUTCMidnight","toISOString","_jsxs","Field","Root","error","_jsx","Label","action","DatePicker","clearLabel","id","defaultMessage","onClear","onBlur","Hint","Error","UTC","getFullYear","getMonth","getDate","MemoizedDateInput","memo"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,MAAMA,SAAAA,iBAAYC,iBAAMC,UAAU,CAChC,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAEC,MAAMC,KAAK,EAAE,GAAGC,KAAAA,EAAO,EAAEC,GAAAA,GAAAA;IACpE,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAMC,QAAQC,aAASZ,CAAAA,IAAAA,CAAAA;AACvB,IAAA,MAAMa,WAAWC,qCAAqCd,CAAAA,IAAAA,CAAAA;IACtD,MAAMe,YAAAA,GAAeC,6BAAgBR,GAAKK,EAAAA,QAAAA,CAAAA;AAC1C,IAAA,MAAM,CAACI,aAAeC,EAAAA,gBAAAA,CAAiB,GAAGpB,gBAAAA,CAAMqB,QAAQ,CAAc,IAAA,CAAA;AAEtE,IAAA,MAAMC,KAAQ,GAAA,OAAOT,KAAMS,CAAAA,KAAK,KAAK,QAAA,GAAW,IAAIC,IAAAA,CAAKV,KAAMS,CAAAA,KAAK,CAAIT,GAAAA,KAAAA,CAAMS,KAAK;AAEnF,IAAA,MAAME,mBAAmB,CAACC,IAAAA,GAAAA;AACxB,QAAA,IAAI,CAACA,IAAM,EAAA;YACTZ,KAAMa,CAAAA,QAAQ,CAACxB,IAAM,EAAA,IAAA,CAAA;YACrBkB,gBAAiB,CAAA,IAAA,CAAA;AACjB,YAAA;AACF;;AAGA,QAAA,MAAMO,UAAUC,aAAcH,CAAAA,IAAAA,CAAAA;;AAE9BZ,QAAAA,KAAAA,CAAMa,QAAQ,CAACxB,IAAMyB,EAAAA,OAAAA,CAAQE,WAAW,EAAA,CAAA;QACxCT,gBAAiBO,CAAAA,OAAAA,CAAAA;AACnB,KAAA;;IAGA,qBACEG,eAAA,CAACC,mBAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOpB,MAAMoB,KAAK;QAAE/B,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAA+B,cAAA,CAACH,mBAAMI,KAAK,EAAA;gBAACC,MAAQ9B,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnC8B,cAACG,CAAAA,uBAAAA,EAAAA;gBACC3B,GAAKO,EAAAA,YAAAA;AACLqB,gBAAAA,UAAAA,EAAY3B,aAAc,CAAA;oBAAE4B,EAAI,EAAA,YAAA;oBAAcC,cAAgB,EAAA;AAAQ,iBAAA,CAAA;gBACtEd,QAAUF,EAAAA,gBAAAA;gBACViB,OAAS,EAAA,IAAA;oBACP5B,KAAMa,CAAAA,QAAQ,CAACxB,IAAM,EAAA,IAAA,CAAA;oBACrBkB,gBAAiB,CAAA,IAAA,CAAA;AACjB,oBAAA;AACF,iBAAA;gBACAsB,MAAQ,EAAA,IAAA;;AAEN,oBAAA,IAAI7B,KAAMS,CAAAA,KAAK,IAAI,CAACA,KAAO,EAAA;AACzBT,wBAAAA,KAAAA,CAAMa,QAAQ,CAACxB,IAAMiB,EAAAA,aAAAA,EAAeU,WAAiB,EAAA,IAAA,IAAA,CAAA;AACvD;AACF,iBAAA;gBACAP,KAAOA,EAAAA,KAAAA;AACN,gBAAA,GAAGb;;AAEN,0BAAAyB,cAAA,CAACH,mBAAMY,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAT,cAAA,CAACH,mBAAMa,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF;AACLine truncated
@@ -0,0 +1,71 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import * as React from 'react';
import { useComposedRefs, Field, DatePicker } from '@strapi/design-system';
import { useIntl } from 'react-intl';
import { useFocusInputField } from '../../hooks/useFocusInputField.mjs';
import { useField } from '../Form.mjs';
const DateInput = /*#__PURE__*/ React.forwardRef(({ name, required, label, hint, labelAction, type: _type, ...props }, ref)=>{
const { formatMessage } = useIntl();
const field = useField(name);
const fieldRef = useFocusInputField(name);
const composedRefs = useComposedRefs(ref, fieldRef);
const [lastValidDate, setLastValidDate] = React.useState(null);
const value = typeof field.value === 'string' ? new Date(field.value) : field.value;
const handleDateChange = (date)=>{
if (!date) {
field.onChange(name, null);
setLastValidDate(null);
return;
}
// Convert to UTC midnight
const utcDate = toUTCMidnight(date);
// Save as ISO string in UTC format
field.onChange(name, utcDate.toISOString());
setLastValidDate(utcDate);
};
// Render the DatePicker with UTC date
return /*#__PURE__*/ jsxs(Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsx(Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsx(DatePicker, {
ref: composedRefs,
clearLabel: formatMessage({
id: 'clearLabel',
defaultMessage: 'Clear'
}),
onChange: handleDateChange,
onClear: ()=>{
field.onChange(name, null);
setLastValidDate(null);
return;
},
onBlur: ()=>{
// When the input is blurred, revert to the last valid date if the current value is invalid
if (field.value && !value) {
field.onChange(name, lastValidDate?.toISOString() ?? null);
}
},
value: value,
...props
}),
/*#__PURE__*/ jsx(Field.Hint, {}),
/*#__PURE__*/ jsx(Field.Error, {})
]
});
});
// Ensure the conversion to UTC midnight
const toUTCMidnight = (date)=>{
return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
};
const MemoizedDateInput = /*#__PURE__*/ React.memo(DateInput);
export { MemoizedDateInput as DateInput };
//# sourceMappingURL=Date.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"Date.mjs","sources":["../../../../../../admin/src/components/FormInputs/Date.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { DatePicker, useComposedRefs, Field } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst DateInput = React.forwardRef<HTMLInputElement, InputProps>(\n ({ name, required, label, hint, labelAction, type: _type, ...props }, ref) => {\n const { formatMessage } = useIntl();\n const field = useField(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n const composedRefs = useComposedRefs(ref, fieldRef);\n const [lastValidDate, setLastValidDate] = React.useState<Date | null>(null);\n\n const value = typeof field.value === 'string' ? new Date(field.value) : field.value;\n\n const handleDateChange = (date: Date | undefined) => {\n if (!date) {\n field.onChange(name, null);\n setLastValidDate(null);\n return;\n }\n\n // Convert to UTC midnight\n const utcDate = toUTCMidnight(date);\n // Save as ISO string in UTC format\n field.onChange(name, utcDate.toISOString());\n setLastValidDate(utcDate);\n };\n\n // Render the DatePicker with UTC date\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <DatePicker\n ref={composedRefs}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n onChange={handleDateChange}\n onClear={() => {\n field.onChange(name, null);\n setLastValidDate(null);\n return;\n }}\n onBlur={() => {\n // When the input is blurred, revert to the last valid date if the current value is invalid\n if (field.value && !value) {\n field.onChange(name, lastValidDate?.toISOString() ?? null);\n }\n }}\n value={value}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\n// Ensure the conversion to UTC midnight\nconst toUTCMidnight = (date: Date) => {\n return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));\n};\n\nconst MemoizedDateInput = React.memo(DateInput);\n\nexport { MemoizedDateInput as DateInput };\n"],"names":["DateInput","React","forwardRef","name","required","label","hint","labelAction","type","_type","props","ref","formatMessage","useIntl","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","lastValidDate","setLastValidDate","useState","value","Date","handleDateChange","date","onChange","utcDate","toUTCMidnight","toISOString","_jsxs","Field","Root","error","_jsx","Label","action","DatePicker","clearLabel","id","defaultMessage","onClear","onBlur","Hint","Error","UTC","getFullYear","getMonth","getDate","MemoizedDateInput","memo"],"mappings":";;;;;;;AAUA,MAAMA,SAAAA,iBAAYC,MAAMC,UAAU,CAChC,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAEC,MAAMC,KAAK,EAAE,GAAGC,KAAAA,EAAO,EAAEC,GAAAA,GAAAA;IACpE,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAC1B,IAAA,MAAMC,QAAQC,QAASZ,CAAAA,IAAAA,CAAAA;AACvB,IAAA,MAAMa,WAAWC,kBAAqCd,CAAAA,IAAAA,CAAAA;IACtD,MAAMe,YAAAA,GAAeC,gBAAgBR,GAAKK,EAAAA,QAAAA,CAAAA;AAC1C,IAAA,MAAM,CAACI,aAAeC,EAAAA,gBAAAA,CAAiB,GAAGpB,KAAAA,CAAMqB,QAAQ,CAAc,IAAA,CAAA;AAEtE,IAAA,MAAMC,KAAQ,GAAA,OAAOT,KAAMS,CAAAA,KAAK,KAAK,QAAA,GAAW,IAAIC,IAAAA,CAAKV,KAAMS,CAAAA,KAAK,CAAIT,GAAAA,KAAAA,CAAMS,KAAK;AAEnF,IAAA,MAAME,mBAAmB,CAACC,IAAAA,GAAAA;AACxB,QAAA,IAAI,CAACA,IAAM,EAAA;YACTZ,KAAMa,CAAAA,QAAQ,CAACxB,IAAM,EAAA,IAAA,CAAA;YACrBkB,gBAAiB,CAAA,IAAA,CAAA;AACjB,YAAA;AACF;;AAGA,QAAA,MAAMO,UAAUC,aAAcH,CAAAA,IAAAA,CAAAA;;AAE9BZ,QAAAA,KAAAA,CAAMa,QAAQ,CAACxB,IAAMyB,EAAAA,OAAAA,CAAQE,WAAW,EAAA,CAAA;QACxCT,gBAAiBO,CAAAA,OAAAA,CAAAA;AACnB,KAAA;;IAGA,qBACEG,IAAA,CAACC,MAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOpB,MAAMoB,KAAK;QAAE/B,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAA+B,GAAA,CAACH,MAAMI,KAAK,EAAA;gBAACC,MAAQ9B,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnC8B,GAACG,CAAAA,UAAAA,EAAAA;gBACC3B,GAAKO,EAAAA,YAAAA;AACLqB,gBAAAA,UAAAA,EAAY3B,aAAc,CAAA;oBAAE4B,EAAI,EAAA,YAAA;oBAAcC,cAAgB,EAAA;AAAQ,iBAAA,CAAA;gBACtEd,QAAUF,EAAAA,gBAAAA;gBACViB,OAAS,EAAA,IAAA;oBACP5B,KAAMa,CAAAA,QAAQ,CAACxB,IAAM,EAAA,IAAA,CAAA;oBACrBkB,gBAAiB,CAAA,IAAA,CAAA;AACjB,oBAAA;AACF,iBAAA;gBACAsB,MAAQ,EAAA,IAAA;;AAEN,oBAAA,IAAI7B,KAAMS,CAAAA,KAAK,IAAI,CAACA,KAAO,EAAA;AACzBT,wBAAAA,KAAAA,CAAMa,QAAQ,CAACxB,IAAMiB,EAAAA,aAAAA,EAAeU,WAAiB,EAAA,IAAA,IAAA,CAAA;AACvD;AACF,iBAAA;gBACAP,KAAOA,EAAAA,KAAAA;AACN,gBAAA,GAAGb;;AAEN,0BAAAyB,GAAA,CAACH,MAAMY,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAT,GAAA,CAACH,MAAMa,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF;AACA,MAAMhB,gBAAgB,CAACH,IAAAA,Line truncated
@@ -0,0 +1,48 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var reactIntl = require('react-intl');
var useFocusInputField = require('../../hooks/useFocusInputField.js');
var Form = require('../Form.js');
const DateTimeInput = /*#__PURE__*/ React.forwardRef(({ name, required, label, hint, labelAction, ...props }, ref)=>{
const { formatMessage } = reactIntl.useIntl();
const field = Form.useField(name);
const fieldRef = useFocusInputField.useFocusInputField(name);
const composedRefs = designSystem.useComposedRefs(ref, fieldRef);
const value = typeof field.value === 'string' ? new Date(field.value) : field.value;
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.DateTimePicker, {
ref: composedRefs,
clearLabel: formatMessage({
id: 'clearLabel',
defaultMessage: 'Clear'
}),
onChange: (date)=>{
// Store ISO string in the field, but Date object in the component value
field.onChange(name, date ? date.toISOString() : null);
},
onClear: ()=>field.onChange(name, null),
value: value,
...props
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Hint, {}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
});
});
const MemoizedDateTimeInput = /*#__PURE__*/ React.memo(DateTimeInput);
exports.DateTimeInput = MemoizedDateTimeInput;
//# sourceMappingURL=DateTime.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DateTime.js","sources":["../../../../../../admin/src/components/FormInputs/DateTime.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { DateTimePicker, useComposedRefs, Field } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst DateTimeInput = forwardRef<HTMLInputElement, InputProps>(\n ({ name, required, label, hint, labelAction, ...props }, ref) => {\n const { formatMessage } = useIntl();\n const field = useField<string | null>(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n const value = typeof field.value === 'string' ? new Date(field.value) : field.value;\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <DateTimePicker\n ref={composedRefs}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n onChange={(date) => {\n // Store ISO string in the field, but Date object in the component value\n field.onChange(name, date ? date.toISOString() : null);\n }}\n onClear={() => field.onChange(name, null)}\n value={value}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedDateTimeInput = memo(DateTimeInput);\n\nexport { MemoizedDateTimeInput as DateTimeInput };\n"],"names":["DateTimeInput","forwardRef","name","required","label","hint","labelAction","props","ref","formatMessage","useIntl","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","value","Date","_jsxs","Field","Root","error","_jsx","Label","action","DateTimePicker","clearLabel","id","defaultMessage","onChange","date","toISOString","onClear","Hint","Error","MemoizedDateTimeInput","memo"],"mappings":";;;;;;;;;AAUA,MAAMA,8BAAgBC,gBACpB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;IACvD,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAMC,QAAQC,aAAwBV,CAAAA,IAAAA,CAAAA;AACtC,IAAA,MAAMW,WAAWC,qCAAqCZ,CAAAA,IAAAA,CAAAA;IAEtD,MAAMa,YAAAA,GAAeC,6BAAgBR,GAAKK,EAAAA,QAAAA,CAAAA;AAC1C,IAAA,MAAMI,KAAQ,GAAA,OAAON,KAAMM,CAAAA,KAAK,KAAK,QAAA,GAAW,IAAIC,IAAAA,CAAKP,KAAMM,CAAAA,KAAK,CAAIN,GAAAA,KAAAA,CAAMM,KAAK;IAEnF,qBACEE,eAAA,CAACC,mBAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOX,MAAMW,KAAK;QAAEpB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAoB,cAAA,CAACH,mBAAMI,KAAK,EAAA;gBAACC,MAAQnB,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCmB,cAACG,CAAAA,2BAAAA,EAAAA;gBACClB,GAAKO,EAAAA,YAAAA;AACLY,gBAAAA,UAAAA,EAAYlB,aAAc,CAAA;oBAAEmB,EAAI,EAAA,YAAA;oBAAcC,cAAgB,EAAA;AAAQ,iBAAA,CAAA;AACtEC,gBAAAA,QAAAA,EAAU,CAACC,IAAAA,GAAAA;;AAETpB,oBAAAA,KAAAA,CAAMmB,QAAQ,CAAC5B,IAAAA,EAAM6B,IAAOA,GAAAA,IAAAA,CAAKC,WAAW,EAAK,GAAA,IAAA,CAAA;AACnD,iBAAA;AACAC,gBAAAA,OAAAA,EAAS,IAAMtB,KAAAA,CAAMmB,QAAQ,CAAC5B,IAAM,EAAA,IAAA,CAAA;gBACpCe,KAAOA,EAAAA,KAAAA;AACN,gBAAA,GAAGV;;AAEN,0BAAAgB,cAAA,CAACH,mBAAMc,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAX,cAAA,CAACH,mBAAMe,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,sCAAwBC,UAAKrC,CAAAA,aAAAA;;;;"}
@@ -0,0 +1,46 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import { memo, forwardRef } from 'react';
import { useComposedRefs, Field, DateTimePicker } from '@strapi/design-system';
import { useIntl } from 'react-intl';
import { useFocusInputField } from '../../hooks/useFocusInputField.mjs';
import { useField } from '../Form.mjs';
const DateTimeInput = /*#__PURE__*/ forwardRef(({ name, required, label, hint, labelAction, ...props }, ref)=>{
const { formatMessage } = useIntl();
const field = useField(name);
const fieldRef = useFocusInputField(name);
const composedRefs = useComposedRefs(ref, fieldRef);
const value = typeof field.value === 'string' ? new Date(field.value) : field.value;
return /*#__PURE__*/ jsxs(Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsx(Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsx(DateTimePicker, {
ref: composedRefs,
clearLabel: formatMessage({
id: 'clearLabel',
defaultMessage: 'Clear'
}),
onChange: (date)=>{
// Store ISO string in the field, but Date object in the component value
field.onChange(name, date ? date.toISOString() : null);
},
onClear: ()=>field.onChange(name, null),
value: value,
...props
}),
/*#__PURE__*/ jsx(Field.Hint, {}),
/*#__PURE__*/ jsx(Field.Error, {})
]
});
});
const MemoizedDateTimeInput = /*#__PURE__*/ memo(DateTimeInput);
export { MemoizedDateTimeInput as DateTimeInput };
//# sourceMappingURL=DateTime.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"DateTime.mjs","sources":["../../../../../../admin/src/components/FormInputs/DateTime.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { DateTimePicker, useComposedRefs, Field } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst DateTimeInput = forwardRef<HTMLInputElement, InputProps>(\n ({ name, required, label, hint, labelAction, ...props }, ref) => {\n const { formatMessage } = useIntl();\n const field = useField<string | null>(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n const value = typeof field.value === 'string' ? new Date(field.value) : field.value;\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <DateTimePicker\n ref={composedRefs}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n onChange={(date) => {\n // Store ISO string in the field, but Date object in the component value\n field.onChange(name, date ? date.toISOString() : null);\n }}\n onClear={() => field.onChange(name, null)}\n value={value}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedDateTimeInput = memo(DateTimeInput);\n\nexport { MemoizedDateTimeInput as DateTimeInput };\n"],"names":["DateTimeInput","forwardRef","name","required","label","hint","labelAction","props","ref","formatMessage","useIntl","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","value","Date","_jsxs","Field","Root","error","_jsx","Label","action","DateTimePicker","clearLabel","id","defaultMessage","onChange","date","toISOString","onClear","Hint","Error","MemoizedDateTimeInput","memo"],"mappings":";;;;;;;AAUA,MAAMA,8BAAgBC,UACpB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;IACvD,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAC1B,IAAA,MAAMC,QAAQC,QAAwBV,CAAAA,IAAAA,CAAAA;AACtC,IAAA,MAAMW,WAAWC,kBAAqCZ,CAAAA,IAAAA,CAAAA;IAEtD,MAAMa,YAAAA,GAAeC,gBAAgBR,GAAKK,EAAAA,QAAAA,CAAAA;AAC1C,IAAA,MAAMI,KAAQ,GAAA,OAAON,KAAMM,CAAAA,KAAK,KAAK,QAAA,GAAW,IAAIC,IAAAA,CAAKP,KAAMM,CAAAA,KAAK,CAAIN,GAAAA,KAAAA,CAAMM,KAAK;IAEnF,qBACEE,IAAA,CAACC,MAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOX,MAAMW,KAAK;QAAEpB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAoB,GAAA,CAACH,MAAMI,KAAK,EAAA;gBAACC,MAAQnB,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCmB,GAACG,CAAAA,cAAAA,EAAAA;gBACClB,GAAKO,EAAAA,YAAAA;AACLY,gBAAAA,UAAAA,EAAYlB,aAAc,CAAA;oBAAEmB,EAAI,EAAA,YAAA;oBAAcC,cAAgB,EAAA;AAAQ,iBAAA,CAAA;AACtEC,gBAAAA,QAAAA,EAAU,CAACC,IAAAA,GAAAA;;AAETpB,oBAAAA,KAAAA,CAAMmB,QAAQ,CAAC5B,IAAAA,EAAM6B,IAAOA,GAAAA,IAAAA,CAAKC,WAAW,EAAK,GAAA,IAAA,CAAA;AACnD,iBAAA;AACAC,gBAAAA,OAAAA,EAAS,IAAMtB,KAAAA,CAAMmB,QAAQ,CAAC5B,IAAM,EAAA,IAAA,CAAA;gBACpCe,KAAOA,EAAAA,KAAAA;AACN,gBAAA,GAAGV;;AAEN,0BAAAgB,GAAA,CAACH,MAAMc,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAX,GAAA,CAACH,MAAMe,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,sCAAwBC,IAAKrC,CAAAA,aAAAA;;;;"}
@@ -0,0 +1,39 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var useFocusInputField = require('../../hooks/useFocusInputField.js');
var Form = require('../Form.js');
const EmailInput = /*#__PURE__*/ React.forwardRef(({ name, required, label, hint, labelAction, ...props }, ref)=>{
const field = Form.useField(name);
const fieldRef = useFocusInputField.useFocusInputField(name);
const composedRefs = designSystem.useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.TextInput, {
ref: composedRefs,
autoComplete: "email",
onChange: field.onChange,
value: field.value,
...props,
type: "email"
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Hint, {}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
});
});
const MemoizedEmailInput = /*#__PURE__*/ React.memo(EmailInput);
exports.EmailInput = MemoizedEmailInput;
//# sourceMappingURL=Email.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Email.js","sources":["../../../../../../admin/src/components/FormInputs/Email.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { TextInput, useComposedRefs, Field } from '@strapi/design-system';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport type { StringProps } from './types';\n\nconst EmailInput = forwardRef<HTMLInputElement, StringProps>(\n ({ name, required, label, hint, labelAction, ...props }, ref) => {\n const field = useField(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <TextInput\n ref={composedRefs}\n autoComplete=\"email\"\n onChange={field.onChange}\n value={field.value}\n {...props}\n type=\"email\"\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedEmailInput = memo(EmailInput);\n\nexport { MemoizedEmailInput as EmailInput };\n"],"names":["EmailInput","forwardRef","name","required","label","hint","labelAction","props","ref","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Label","action","TextInput","autoComplete","onChange","value","type","Hint","Error","MemoizedEmailInput","memo"],"mappings":";;;;;;;;AASA,MAAMA,2BAAaC,gBACjB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;AACvD,IAAA,MAAMC,QAAQC,aAASR,CAAAA,IAAAA,CAAAA;AACvB,IAAA,MAAMS,WAAWC,qCAAqCV,CAAAA,IAAAA,CAAAA;IAEtD,MAAMW,YAAAA,GAAeC,6BAAgBN,GAAKG,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,eAAA,CAACC,mBAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAEhB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAgB,cAAA,CAACH,mBAAMI,KAAK,EAAA;gBAACC,MAAQf,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCe,cAACG,CAAAA,sBAAAA,EAAAA;gBACCd,GAAKK,EAAAA,YAAAA;gBACLU,YAAa,EAAA,OAAA;AACbC,gBAAAA,QAAAA,EAAUf,MAAMe,QAAQ;AACxBC,gBAAAA,KAAAA,EAAOhB,MAAMgB,KAAK;AACjB,gBAAA,GAAGlB,KAAK;gBACTmB,IAAK,EAAA;;AAEP,0BAAAP,cAAA,CAACH,mBAAMW,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAR,cAAA,CAACH,mBAAMY,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,mCAAqBC,UAAK9B,CAAAA,UAAAA;;;;"}
@@ -0,0 +1,37 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import { memo, forwardRef } from 'react';
import { useComposedRefs, Field, TextInput } from '@strapi/design-system';
import { useFocusInputField } from '../../hooks/useFocusInputField.mjs';
import { useField } from '../Form.mjs';
const EmailInput = /*#__PURE__*/ forwardRef(({ name, required, label, hint, labelAction, ...props }, ref)=>{
const field = useField(name);
const fieldRef = useFocusInputField(name);
const composedRefs = useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxs(Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsx(Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsx(TextInput, {
ref: composedRefs,
autoComplete: "email",
onChange: field.onChange,
value: field.value,
...props,
type: "email"
}),
/*#__PURE__*/ jsx(Field.Hint, {}),
/*#__PURE__*/ jsx(Field.Error, {})
]
});
});
const MemoizedEmailInput = /*#__PURE__*/ memo(EmailInput);
export { MemoizedEmailInput as EmailInput };
//# sourceMappingURL=Email.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"Email.mjs","sources":["../../../../../../admin/src/components/FormInputs/Email.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { TextInput, useComposedRefs, Field } from '@strapi/design-system';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport type { StringProps } from './types';\n\nconst EmailInput = forwardRef<HTMLInputElement, StringProps>(\n ({ name, required, label, hint, labelAction, ...props }, ref) => {\n const field = useField(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <TextInput\n ref={composedRefs}\n autoComplete=\"email\"\n onChange={field.onChange}\n value={field.value}\n {...props}\n type=\"email\"\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedEmailInput = memo(EmailInput);\n\nexport { MemoizedEmailInput as EmailInput };\n"],"names":["EmailInput","forwardRef","name","required","label","hint","labelAction","props","ref","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Label","action","TextInput","autoComplete","onChange","value","type","Hint","Error","MemoizedEmailInput","memo"],"mappings":";;;;;;AASA,MAAMA,2BAAaC,UACjB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;AACvD,IAAA,MAAMC,QAAQC,QAASR,CAAAA,IAAAA,CAAAA;AACvB,IAAA,MAAMS,WAAWC,kBAAqCV,CAAAA,IAAAA,CAAAA;IAEtD,MAAMW,YAAAA,GAAeC,gBAAgBN,GAAKG,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,IAAA,CAACC,MAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAEhB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAgB,GAAA,CAACH,MAAMI,KAAK,EAAA;gBAACC,MAAQf,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCe,GAACG,CAAAA,SAAAA,EAAAA;gBACCd,GAAKK,EAAAA,YAAAA;gBACLU,YAAa,EAAA,OAAA;AACbC,gBAAAA,QAAAA,EAAUf,MAAMe,QAAQ;AACxBC,gBAAAA,KAAAA,EAAOhB,MAAMgB,KAAK;AACjB,gBAAA,GAAGlB,KAAK;gBACTmB,IAAK,EAAA;;AAEP,0BAAAP,GAAA,CAACH,MAAMW,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAR,GAAA,CAACH,MAAMY,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,mCAAqBC,IAAK9B,CAAAA,UAAAA;;;;"}
@@ -0,0 +1,60 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var reactIntl = require('react-intl');
var useFocusInputField = require('../../hooks/useFocusInputField.js');
var Form = require('../Form.js');
const EnumerationInput = /*#__PURE__*/ React.forwardRef(({ name, required, label, hint, labelAction, options = [], ...props }, ref)=>{
const { formatMessage } = reactIntl.useIntl();
const field = Form.useField(name);
const fieldRef = useFocusInputField.useFocusInputField(name);
const composedRefs = designSystem.useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.SingleSelect, {
ref: composedRefs,
onChange: (value)=>{
field.onChange(name, value);
},
value: field.value,
...props,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.SingleSelectOption, {
value: "",
disabled: required,
hidden: required,
children: formatMessage({
id: 'components.InputSelect.option.placeholder',
defaultMessage: 'Choose here'
})
}),
options.map(({ value, label, disabled, hidden })=>{
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.SingleSelectOption, {
value: value,
disabled: disabled,
hidden: hidden,
children: label ?? value
}, value);
})
]
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Hint, {}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
});
});
const MemoizedEnumerationInput = /*#__PURE__*/ React.memo(EnumerationInput);
exports.EnumerationInput = MemoizedEnumerationInput;
//# sourceMappingURL=Enumeration.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Enumeration.js","sources":["../../../../../../admin/src/components/FormInputs/Enumeration.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { SingleSelect, SingleSelectOption, useComposedRefs, Field } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { EnumerationProps } from './types';\n\nconst EnumerationInput = forwardRef<HTMLDivElement, EnumerationProps>(\n ({ name, required, label, hint, labelAction, options = [], ...props }, ref) => {\n const { formatMessage } = useIntl();\n const field = useField(name);\n const fieldRef = useFocusInputField<HTMLDivElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <SingleSelect\n ref={composedRefs}\n onChange={(value) => {\n field.onChange(name, value);\n }}\n value={field.value}\n {...props}\n >\n <SingleSelectOption value=\"\" disabled={required} hidden={required}>\n {formatMessage({\n id: 'components.InputSelect.option.placeholder',\n defaultMessage: 'Choose here',\n })}\n </SingleSelectOption>\n {options.map(({ value, label, disabled, hidden }) => {\n return (\n <SingleSelectOption key={value} value={value} disabled={disabled} hidden={hidden}>\n {label ?? value}\n </SingleSelectOption>\n );\n })}\n </SingleSelect>\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedEnumerationInput = memo(EnumerationInput);\n\nexport { MemoizedEnumerationInput as EnumerationInput };\n"],"names":["EnumerationInput","forwardRef","name","required","label","hint","labelAction","options","props","ref","formatMessage","useIntl","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Label","action","SingleSelect","onChange","value","SingleSelectOption","disabled","hidden","id","defaultMessage","map","Hint","Error","MemoizedEnumerationInput","memo"],"mappings":";;;;;;;;;AAUA,MAAMA,iCAAmBC,gBACvB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAEC,OAAAA,GAAU,EAAE,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;IACrE,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAMC,QAAQC,aAASX,CAAAA,IAAAA,CAAAA;AACvB,IAAA,MAAMY,WAAWC,qCAAmCb,CAAAA,IAAAA,CAAAA;IAEpD,MAAMc,YAAAA,GAAeC,6BAAgBR,GAAKK,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,eAAA,CAACC,mBAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAEnB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAmB,cAAA,CAACH,mBAAMI,KAAK,EAAA;gBAACC,MAAQlB,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCc,eAACO,CAAAA,yBAAAA,EAAAA;gBACChB,GAAKO,EAAAA,YAAAA;AACLU,gBAAAA,QAAAA,EAAU,CAACC,KAAAA,GAAAA;oBACTf,KAAMc,CAAAA,QAAQ,CAACxB,IAAMyB,EAAAA,KAAAA,CAAAA;AACvB,iBAAA;AACAA,gBAAAA,KAAAA,EAAOf,MAAMe,KAAK;AACjB,gBAAA,GAAGnB,KAAK;;kCAETc,cAACM,CAAAA,+BAAAA,EAAAA;wBAAmBD,KAAM,EAAA,EAAA;wBAAGE,QAAU1B,EAAAA,QAAAA;wBAAU2B,MAAQ3B,EAAAA,QAAAA;kCACtDO,aAAc,CAAA;4BACbqB,EAAI,EAAA,2CAAA;4BACJC,cAAgB,EAAA;AAClB,yBAAA;;oBAEDzB,OAAQ0B,CAAAA,GAAG,CAAC,CAAC,EAAEN,KAAK,EAAEvB,KAAK,EAAEyB,QAAQ,EAAEC,MAAM,EAAE,GAAA;AAC9C,wBAAA,qBACER,cAACM,CAAAA,+BAAAA,EAAAA;4BAA+BD,KAAOA,EAAAA,KAAAA;4BAAOE,QAAUA,EAAAA,QAAAA;4BAAUC,MAAQA,EAAAA,MAAAA;sCACvE1B,KAASuB,IAAAA;AADaA,yBAAAA,EAAAA,KAAAA,CAAAA;AAI7B,qBAAA;;;AAEF,0BAAAL,cAAA,CAACH,mBAAMe,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAZ,cAAA,CAACH,mBAAMgB,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,yCAA2BC,UAAKrC,CAAAA,gBAAAA;;;;"}
@@ -0,0 +1,58 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import { memo, forwardRef } from 'react';
import { useComposedRefs, Field, SingleSelect, SingleSelectOption } from '@strapi/design-system';
import { useIntl } from 'react-intl';
import { useFocusInputField } from '../../hooks/useFocusInputField.mjs';
import { useField } from '../Form.mjs';
const EnumerationInput = /*#__PURE__*/ forwardRef(({ name, required, label, hint, labelAction, options = [], ...props }, ref)=>{
const { formatMessage } = useIntl();
const field = useField(name);
const fieldRef = useFocusInputField(name);
const composedRefs = useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxs(Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsx(Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsxs(SingleSelect, {
ref: composedRefs,
onChange: (value)=>{
field.onChange(name, value);
},
value: field.value,
...props,
children: [
/*#__PURE__*/ jsx(SingleSelectOption, {
value: "",
disabled: required,
hidden: required,
children: formatMessage({
id: 'components.InputSelect.option.placeholder',
defaultMessage: 'Choose here'
})
}),
options.map(({ value, label, disabled, hidden })=>{
return /*#__PURE__*/ jsx(SingleSelectOption, {
value: value,
disabled: disabled,
hidden: hidden,
children: label ?? value
}, value);
})
]
}),
/*#__PURE__*/ jsx(Field.Hint, {}),
/*#__PURE__*/ jsx(Field.Error, {})
]
});
});
const MemoizedEnumerationInput = /*#__PURE__*/ memo(EnumerationInput);
export { MemoizedEnumerationInput as EnumerationInput };
//# sourceMappingURL=Enumeration.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"Enumeration.mjs","sources":["../../../../../../admin/src/components/FormInputs/Enumeration.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { SingleSelect, SingleSelectOption, useComposedRefs, Field } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { EnumerationProps } from './types';\n\nconst EnumerationInput = forwardRef<HTMLDivElement, EnumerationProps>(\n ({ name, required, label, hint, labelAction, options = [], ...props }, ref) => {\n const { formatMessage } = useIntl();\n const field = useField(name);\n const fieldRef = useFocusInputField<HTMLDivElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <SingleSelect\n ref={composedRefs}\n onChange={(value) => {\n field.onChange(name, value);\n }}\n value={field.value}\n {...props}\n >\n <SingleSelectOption value=\"\" disabled={required} hidden={required}>\n {formatMessage({\n id: 'components.InputSelect.option.placeholder',\n defaultMessage: 'Choose here',\n })}\n </SingleSelectOption>\n {options.map(({ value, label, disabled, hidden }) => {\n return (\n <SingleSelectOption key={value} value={value} disabled={disabled} hidden={hidden}>\n {label ?? value}\n </SingleSelectOption>\n );\n })}\n </SingleSelect>\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedEnumerationInput = memo(EnumerationInput);\n\nexport { MemoizedEnumerationInput as EnumerationInput };\n"],"names":["EnumerationInput","forwardRef","name","required","label","hint","labelAction","options","props","ref","formatMessage","useIntl","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Label","action","SingleSelect","onChange","value","SingleSelectOption","disabled","hidden","id","defaultMessage","map","Hint","Error","MemoizedEnumerationInput","memo"],"mappings":";;;;;;;AAUA,MAAMA,iCAAmBC,UACvB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAEC,OAAAA,GAAU,EAAE,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;IACrE,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAC1B,IAAA,MAAMC,QAAQC,QAASX,CAAAA,IAAAA,CAAAA;AACvB,IAAA,MAAMY,WAAWC,kBAAmCb,CAAAA,IAAAA,CAAAA;IAEpD,MAAMc,YAAAA,GAAeC,gBAAgBR,GAAKK,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,IAAA,CAACC,MAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAEnB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAmB,GAAA,CAACH,MAAMI,KAAK,EAAA;gBAACC,MAAQlB,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCc,IAACO,CAAAA,YAAAA,EAAAA;gBACChB,GAAKO,EAAAA,YAAAA;AACLU,gBAAAA,QAAAA,EAAU,CAACC,KAAAA,GAAAA;oBACTf,KAAMc,CAAAA,QAAQ,CAACxB,IAAMyB,EAAAA,KAAAA,CAAAA;AACvB,iBAAA;AACAA,gBAAAA,KAAAA,EAAOf,MAAMe,KAAK;AACjB,gBAAA,GAAGnB,KAAK;;kCAETc,GAACM,CAAAA,kBAAAA,EAAAA;wBAAmBD,KAAM,EAAA,EAAA;wBAAGE,QAAU1B,EAAAA,QAAAA;wBAAU2B,MAAQ3B,EAAAA,QAAAA;kCACtDO,aAAc,CAAA;4BACbqB,EAAI,EAAA,2CAAA;4BACJC,cAAgB,EAAA;AAClB,yBAAA;;oBAEDzB,OAAQ0B,CAAAA,GAAG,CAAC,CAAC,EAAEN,KAAK,EAAEvB,KAAK,EAAEyB,QAAQ,EAAEC,MAAM,EAAE,GAAA;AAC9C,wBAAA,qBACER,GAACM,CAAAA,kBAAAA,EAAAA;4BAA+BD,KAAOA,EAAAA,KAAAA;4BAAOE,QAAUA,EAAAA,QAAAA;4BAAUC,MAAQA,EAAAA,MAAAA;sCACvE1B,KAASuB,IAAAA;AADaA,yBAAAA,EAAAA,KAAAA,CAAAA;AAI7B,qBAAA;;;AAEF,0BAAAL,GAAA,CAACH,MAAMe,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAZ,GAAA,CAACH,MAAMgB,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,yCAA2BC,IAAKrC,CAAAA,gBAAAA;;;;"}
@@ -0,0 +1,62 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var useFocusInputField = require('../../hooks/useFocusInputField.js');
var Form = require('../Form.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const JsonInput = /*#__PURE__*/ React__namespace.forwardRef(({ name, required, label, hint, labelAction, ...props }, ref)=>{
const field = Form.useField(name);
const fieldRef = useFocusInputField.useFocusInputField(name);
const composedRefs = designSystem.useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.JSONInput, {
ref: composedRefs,
value: typeof field.value == 'object' ? JSON.stringify(field.value, null, 2) : field.value,
onChange: (json)=>{
// Default to null when the field is not required and there is no input value
const value = required && !json.length ? null : json;
field.onChange(name, value);
},
minHeight: `25.2rem`,
maxHeight: `50.4rem`,
...props
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Hint, {}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
});
});
const MemoizedJsonInput = /*#__PURE__*/ React__namespace.memo(JsonInput);
exports.JsonInput = MemoizedJsonInput;
//# sourceMappingURL=Json.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Json.js","sources":["../../../../../../admin/src/components/FormInputs/Json.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n JSONInput as JSONInputImpl,\n useComposedRefs,\n Field,\n JSONInputRef,\n} from '@strapi/design-system';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst JsonInput = React.forwardRef<JSONInputRef, InputProps>(\n ({ name, required, label, hint, labelAction, ...props }, ref) => {\n const field = useField(name);\n const fieldRef = useFocusInputField(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <JSONInputImpl\n ref={composedRefs}\n value={\n typeof field.value == 'object' ? JSON.stringify(field.value, null, 2) : field.value\n }\n onChange={(json) => {\n // Default to null when the field is not required and there is no input value\n const value = required && !json.length ? null : json;\n field.onChange(name, value);\n }}\n minHeight={`25.2rem`}\n maxHeight={`50.4rem`}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedJsonInput = React.memo(JsonInput);\n\nexport { MemoizedJsonInput as JsonInput };\n"],"names":["JsonInput","React","forwardRef","name","required","label","hint","labelAction","props","ref","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Label","action","JSONInputImpl","value","JSON","stringify","onChange","json","length","minHeight","maxHeight","Hint","Error","MemoizedJsonInput","memo"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,MAAMA,0BAAYC,gBAAMC,CAAAA,UAAU,CAChC,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;AACvD,IAAA,MAAMC,QAAQC,aAASR,CAAAA,IAAAA,CAAAA;AACvB,IAAA,MAAMS,WAAWC,qCAAmBV,CAAAA,IAAAA,CAAAA;IAEpC,MAAMW,YAAAA,GAAeC,6BAAgBN,GAAKG,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,eAAA,CAACC,mBAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAEhB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAgB,cAAA,CAACH,mBAAMI,KAAK,EAAA;gBAACC,MAAQf,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCe,cAACG,CAAAA,sBAAAA,EAAAA;gBACCd,GAAKK,EAAAA,YAAAA;AACLU,gBAAAA,KAAAA,EACE,OAAOd,KAAAA,CAAMc,KAAK,IAAI,WAAWC,IAAKC,CAAAA,SAAS,CAAChB,KAAAA,CAAMc,KAAK,EAAE,IAAM,EAAA,CAAA,CAAA,GAAKd,MAAMc,KAAK;AAErFG,gBAAAA,QAAAA,EAAU,CAACC,IAAAA,GAAAA;;AAET,oBAAA,MAAMJ,QAAQpB,QAAY,IAAA,CAACwB,IAAKC,CAAAA,MAAM,GAAG,IAAOD,GAAAA,IAAAA;oBAChDlB,KAAMiB,CAAAA,QAAQ,CAACxB,IAAMqB,EAAAA,KAAAA,CAAAA;AACvB,iBAAA;gBACAM,SAAW,EAAA,CAAC,OAAO,CAAC;gBACpBC,SAAW,EAAA,CAAC,OAAO,CAAC;AACnB,gBAAA,GAAGvB;;AAEN,0BAAAY,cAAA,CAACH,mBAAMe,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAZ,cAAA,CAACH,mBAAMgB,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGIC,MAAAA,iBAAAA,iBAAoBjC,gBAAMkC,CAAAA,IAAI,CAACnC,SAAAA;;;;"}
@@ -0,0 +1,41 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import * as React from 'react';
import { useComposedRefs, Field, JSONInput } from '@strapi/design-system';
import { useFocusInputField } from '../../hooks/useFocusInputField.mjs';
import { useField } from '../Form.mjs';
const JsonInput = /*#__PURE__*/ React.forwardRef(({ name, required, label, hint, labelAction, ...props }, ref)=>{
const field = useField(name);
const fieldRef = useFocusInputField(name);
const composedRefs = useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxs(Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsx(Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsx(JSONInput, {
ref: composedRefs,
value: typeof field.value == 'object' ? JSON.stringify(field.value, null, 2) : field.value,
onChange: (json)=>{
// Default to null when the field is not required and there is no input value
const value = required && !json.length ? null : json;
field.onChange(name, value);
},
minHeight: `25.2rem`,
maxHeight: `50.4rem`,
...props
}),
/*#__PURE__*/ jsx(Field.Hint, {}),
/*#__PURE__*/ jsx(Field.Error, {})
]
});
});
const MemoizedJsonInput = /*#__PURE__*/ React.memo(JsonInput);
export { MemoizedJsonInput as JsonInput };
//# sourceMappingURL=Json.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"Json.mjs","sources":["../../../../../../admin/src/components/FormInputs/Json.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n JSONInput as JSONInputImpl,\n useComposedRefs,\n Field,\n JSONInputRef,\n} from '@strapi/design-system';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst JsonInput = React.forwardRef<JSONInputRef, InputProps>(\n ({ name, required, label, hint, labelAction, ...props }, ref) => {\n const field = useField(name);\n const fieldRef = useFocusInputField(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <JSONInputImpl\n ref={composedRefs}\n value={\n typeof field.value == 'object' ? JSON.stringify(field.value, null, 2) : field.value\n }\n onChange={(json) => {\n // Default to null when the field is not required and there is no input value\n const value = required && !json.length ? null : json;\n field.onChange(name, value);\n }}\n minHeight={`25.2rem`}\n maxHeight={`50.4rem`}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedJsonInput = React.memo(JsonInput);\n\nexport { MemoizedJsonInput as JsonInput };\n"],"names":["JsonInput","React","forwardRef","name","required","label","hint","labelAction","props","ref","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Label","action","JSONInputImpl","value","JSON","stringify","onChange","json","length","minHeight","maxHeight","Hint","Error","MemoizedJsonInput","memo"],"mappings":";;;;;;AAcA,MAAMA,0BAAYC,KAAMC,CAAAA,UAAU,CAChC,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;AACvD,IAAA,MAAMC,QAAQC,QAASR,CAAAA,IAAAA,CAAAA;AACvB,IAAA,MAAMS,WAAWC,kBAAmBV,CAAAA,IAAAA,CAAAA;IAEpC,MAAMW,YAAAA,GAAeC,gBAAgBN,GAAKG,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,IAAA,CAACC,MAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAEhB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAgB,GAAA,CAACH,MAAMI,KAAK,EAAA;gBAACC,MAAQf,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCe,GAACG,CAAAA,SAAAA,EAAAA;gBACCd,GAAKK,EAAAA,YAAAA;AACLU,gBAAAA,KAAAA,EACE,OAAOd,KAAAA,CAAMc,KAAK,IAAI,WAAWC,IAAKC,CAAAA,SAAS,CAAChB,KAAAA,CAAMc,KAAK,EAAE,IAAM,EAAA,CAAA,CAAA,GAAKd,MAAMc,KAAK;AAErFG,gBAAAA,QAAAA,EAAU,CAACC,IAAAA,GAAAA;;AAET,oBAAA,MAAMJ,QAAQpB,QAAY,IAAA,CAACwB,IAAKC,CAAAA,MAAM,GAAG,IAAOD,GAAAA,IAAAA;oBAChDlB,KAAMiB,CAAAA,QAAQ,CAACxB,IAAMqB,EAAAA,KAAAA,CAAAA;AACvB,iBAAA;gBACAM,SAAW,EAAA,CAAC,OAAO,CAAC;gBACpBC,SAAW,EAAA,CAAC,OAAO,CAAC;AACnB,gBAAA,GAAGvB;;AAEN,0BAAAY,GAAA,CAACH,MAAMe,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAZ,GAAA,CAACH,MAAMgB,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGIC,MAAAA,iBAAAA,iBAAoBjC,KAAMkC,CAAAA,IAAI,CAACnC,SAAAA;;;;"}
@@ -0,0 +1,42 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var useFocusInputField = require('../../hooks/useFocusInputField.js');
var Form = require('../Form.js');
const NumberInputImpl = /*#__PURE__*/ React.forwardRef(({ name, required, label, hint, labelAction, type, ...props }, ref)=>{
const field = Form.useField(name);
const fieldRef = useFocusInputField.useFocusInputField(name);
const composedRefs = designSystem.useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.NumberInput, {
ref: composedRefs,
onValueChange: (value)=>{
// Convert undefined to null to store it in the form state
// See https://github.com/strapi/strapi/issues/22533
field.onChange(name, value ?? null);
},
step: type === 'float' || type == 'decimal' ? 0.01 : 1,
value: field.value ?? undefined,
...props
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Hint, {}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
});
});
const MemoizedNumberInput = /*#__PURE__*/ React.memo(NumberInputImpl);
exports.NumberInput = MemoizedNumberInput;
//# sourceMappingURL=Number.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Number.js","sources":["../../../../../../admin/src/components/FormInputs/Number.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { NumberInput, useComposedRefs, Field } from '@strapi/design-system';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst NumberInputImpl = forwardRef<HTMLInputElement, InputProps>(\n ({ name, required, label, hint, labelAction, type, ...props }, ref) => {\n const field = useField<number | null>(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <NumberInput\n ref={composedRefs}\n onValueChange={(value) => {\n // Convert undefined to null to store it in the form state\n // See https://github.com/strapi/strapi/issues/22533\n field.onChange(name, value ?? null);\n }}\n step={type === 'float' || type == 'decimal' ? 0.01 : 1}\n value={field.value ?? undefined}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedNumberInput = memo(NumberInputImpl);\n\nexport { MemoizedNumberInput as NumberInput };\n"],"names":["NumberInputImpl","forwardRef","name","required","label","hint","labelAction","type","props","ref","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Label","action","NumberInput","onValueChange","value","onChange","step","undefined","Hint","Error","MemoizedNumberInput","memo"],"mappings":";;;;;;;;AASA,MAAMA,gCAAkBC,gBACtB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAEC,IAAI,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;AAC7D,IAAA,MAAMC,QAAQC,aAAwBT,CAAAA,IAAAA,CAAAA;AACtC,IAAA,MAAMU,WAAWC,qCAAqCX,CAAAA,IAAAA,CAAAA;IAEtD,MAAMY,YAAAA,GAAeC,6BAAgBN,GAAKG,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,eAAA,CAACC,mBAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAEjB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAiB,cAAA,CAACH,mBAAMI,KAAK,EAAA;gBAACC,MAAQhB,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCgB,cAACG,CAAAA,wBAAAA,EAAAA;gBACCd,GAAKK,EAAAA,YAAAA;AACLU,gBAAAA,aAAAA,EAAe,CAACC,KAAAA,GAAAA;;;oBAGdf,KAAMgB,CAAAA,QAAQ,CAACxB,IAAAA,EAAMuB,KAAS,IAAA,IAAA,CAAA;AAChC,iBAAA;AACAE,gBAAAA,IAAAA,EAAMpB,IAAS,KAAA,OAAA,IAAWA,IAAQ,IAAA,SAAA,GAAY,IAAO,GAAA,CAAA;gBACrDkB,KAAOf,EAAAA,KAAAA,CAAMe,KAAK,IAAIG,SAAAA;AACrB,gBAAA,GAAGpB;;AAEN,0BAAAY,cAAA,CAACH,mBAAMY,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAT,cAAA,CAACH,mBAAMa,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,oCAAsBC,UAAKhC,CAAAA,eAAAA;;;;"}
@@ -0,0 +1,40 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import { memo, forwardRef } from 'react';
import { useComposedRefs, Field, NumberInput } from '@strapi/design-system';
import { useFocusInputField } from '../../hooks/useFocusInputField.mjs';
import { useField } from '../Form.mjs';
const NumberInputImpl = /*#__PURE__*/ forwardRef(({ name, required, label, hint, labelAction, type, ...props }, ref)=>{
const field = useField(name);
const fieldRef = useFocusInputField(name);
const composedRefs = useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxs(Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsx(Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsx(NumberInput, {
ref: composedRefs,
onValueChange: (value)=>{
// Convert undefined to null to store it in the form state
// See https://github.com/strapi/strapi/issues/22533
field.onChange(name, value ?? null);
},
step: type === 'float' || type == 'decimal' ? 0.01 : 1,
value: field.value ?? undefined,
...props
}),
/*#__PURE__*/ jsx(Field.Hint, {}),
/*#__PURE__*/ jsx(Field.Error, {})
]
});
});
const MemoizedNumberInput = /*#__PURE__*/ memo(NumberInputImpl);
export { MemoizedNumberInput as NumberInput };
//# sourceMappingURL=Number.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"Number.mjs","sources":["../../../../../../admin/src/components/FormInputs/Number.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { NumberInput, useComposedRefs, Field } from '@strapi/design-system';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst NumberInputImpl = forwardRef<HTMLInputElement, InputProps>(\n ({ name, required, label, hint, labelAction, type, ...props }, ref) => {\n const field = useField<number | null>(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <NumberInput\n ref={composedRefs}\n onValueChange={(value) => {\n // Convert undefined to null to store it in the form state\n // See https://github.com/strapi/strapi/issues/22533\n field.onChange(name, value ?? null);\n }}\n step={type === 'float' || type == 'decimal' ? 0.01 : 1}\n value={field.value ?? undefined}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedNumberInput = memo(NumberInputImpl);\n\nexport { MemoizedNumberInput as NumberInput };\n"],"names":["NumberInputImpl","forwardRef","name","required","label","hint","labelAction","type","props","ref","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Label","action","NumberInput","onValueChange","value","onChange","step","undefined","Hint","Error","MemoizedNumberInput","memo"],"mappings":";;;;;;AASA,MAAMA,gCAAkBC,UACtB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAEC,IAAI,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;AAC7D,IAAA,MAAMC,QAAQC,QAAwBT,CAAAA,IAAAA,CAAAA;AACtC,IAAA,MAAMU,WAAWC,kBAAqCX,CAAAA,IAAAA,CAAAA;IAEtD,MAAMY,YAAAA,GAAeC,gBAAgBN,GAAKG,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,IAAA,CAACC,MAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAEjB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAiB,GAAA,CAACH,MAAMI,KAAK,EAAA;gBAACC,MAAQhB,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCgB,GAACG,CAAAA,WAAAA,EAAAA;gBACCd,GAAKK,EAAAA,YAAAA;AACLU,gBAAAA,aAAAA,EAAe,CAACC,KAAAA,GAAAA;;;oBAGdf,KAAMgB,CAAAA,QAAQ,CAACxB,IAAAA,EAAMuB,KAAS,IAAA,IAAA,CAAA;AAChC,iBAAA;AACAE,gBAAAA,IAAAA,EAAMpB,IAAS,KAAA,OAAA,IAAWA,IAAQ,IAAA,SAAA,GAAY,IAAO,GAAA,CAAA;gBACrDkB,KAAOf,EAAAA,KAAAA,CAAMe,KAAK,IAAIG,SAAAA;AACrB,gBAAA,GAAGpB;;AAEN,0BAAAY,GAAA,CAACH,MAAMY,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAT,GAAA,CAACH,MAAMa,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,oCAAsBC,IAAKhC,CAAAA,eAAAA;;;;"}
@@ -0,0 +1,57 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var reactIntl = require('react-intl');
var useFocusInputField = require('../../hooks/useFocusInputField.js');
var Form = require('../Form.js');
const PasswordInput = /*#__PURE__*/ React.forwardRef(({ name, required, label, hint, labelAction, ...props }, ref)=>{
const [showPassword, setShowPassword] = React.useState(false);
const { formatMessage } = reactIntl.useIntl();
const field = Form.useField(name);
const fieldRef = useFocusInputField.useFocusInputField(name);
const composedRefs = designSystem.useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.TextInput, {
ref: composedRefs,
autoComplete: "password",
endAction: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Action, {
label: formatMessage({
id: 'Auth.form.password.show-password',
defaultMessage: 'Show password'
}),
onClick: ()=>{
setShowPassword((prev)=>!prev);
},
children: showPassword ? /*#__PURE__*/ jsxRuntime.jsx(icons.Eye, {
fill: "neutral500"
}) : /*#__PURE__*/ jsxRuntime.jsx(icons.EyeStriked, {
fill: "neutral500"
})
}),
onChange: field.onChange,
value: field.value,
...props,
type: showPassword ? 'text' : 'password'
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Hint, {}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
});
});
const MemoizedPasswordInput = /*#__PURE__*/ React.memo(PasswordInput);
exports.PasswordInput = MemoizedPasswordInput;
//# sourceMappingURL=Password.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Password.js","sources":["../../../../../../admin/src/components/FormInputs/Password.tsx"],"sourcesContent":["import { forwardRef, memo, useState } from 'react';\n\nimport { TextInput, useComposedRefs, Field } from '@strapi/design-system';\nimport { Eye, EyeStriked } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport type { StringProps } from './types';\n\nconst PasswordInput = forwardRef<HTMLInputElement, StringProps>(\n ({ name, required, label, hint, labelAction, ...props }, ref) => {\n const [showPassword, setShowPassword] = useState(false);\n const { formatMessage } = useIntl();\n const field = useField(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <TextInput\n ref={composedRefs}\n autoComplete=\"password\"\n endAction={\n <Field.Action\n label={formatMessage({\n id: 'Auth.form.password.show-password',\n defaultMessage: 'Show password',\n })}\n onClick={() => {\n setShowPassword((prev) => !prev);\n }}\n >\n {showPassword ? <Eye fill=\"neutral500\" /> : <EyeStriked fill=\"neutral500\" />}\n </Field.Action>\n }\n onChange={field.onChange}\n value={field.value}\n {...props}\n type={showPassword ? 'text' : 'password'}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedPasswordInput = memo(PasswordInput);\n\nexport { MemoizedPasswordInput as PasswordInput };\n"],"names":["PasswordInput","forwardRef","name","required","label","hint","labelAction","props","ref","showPassword","setShowPassword","useState","formatMessage","useIntl","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Label","action","TextInput","autoComplete","endAction","Action","id","defaultMessage","onClick","prev","Eye","fill","EyeStriked","onChange","value","type","Hint","Error","MemoizedPasswordInput","memo"],"mappings":";;;;;;;;;;AAWA,MAAMA,8BAAgBC,gBACpB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;AACvD,IAAA,MAAM,CAACC,YAAAA,EAAcC,eAAgB,CAAA,GAAGC,cAAS,CAAA,KAAA,CAAA;IACjD,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAMC,QAAQC,aAASb,CAAAA,IAAAA,CAAAA;AACvB,IAAA,MAAMc,WAAWC,qCAAqCf,CAAAA,IAAAA,CAAAA;IAEtD,MAAMgB,YAAAA,GAAeC,6BAAgBX,GAAKQ,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,eAAA,CAACC,mBAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAErB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAqB,cAAA,CAACH,mBAAMI,KAAK,EAAA;gBAACC,MAAQpB,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCoB,cAACG,CAAAA,sBAAAA,EAAAA;gBACCnB,GAAKU,EAAAA,YAAAA;gBACLU,YAAa,EAAA,UAAA;gBACbC,SACE,gBAAAL,cAAA,CAACH,mBAAMS,MAAM,EAAA;AACX1B,oBAAAA,KAAAA,EAAOQ,aAAc,CAAA;wBACnBmB,EAAI,EAAA,kCAAA;wBACJC,cAAgB,EAAA;AAClB,qBAAA,CAAA;oBACAC,OAAS,EAAA,IAAA;wBACPvB,eAAgB,CAAA,CAACwB,OAAS,CAACA,IAAAA,CAAAA;AAC7B,qBAAA;AAECzB,oBAAAA,QAAAA,EAAAA,YAAAA,iBAAee,cAACW,CAAAA,SAAAA,EAAAA;wBAAIC,IAAK,EAAA;uCAAkBZ,cAACa,CAAAA,gBAAAA,EAAAA;wBAAWD,IAAK,EAAA;;;AAGjEE,gBAAAA,QAAAA,EAAUxB,MAAMwB,QAAQ;AACxBC,gBAAAA,KAAAA,EAAOzB,MAAMyB,KAAK;AACjB,gBAAA,GAAGhC,KAAK;AACTiC,gBAAAA,IAAAA,EAAM/B,eAAe,MAAS,GAAA;;AAEhC,0BAAAe,cAAA,CAACH,mBAAMoB,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAjB,cAAA,CAACH,mBAAMqB,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,sCAAwBC,UAAK5C,CAAAA,aAAAA;;;;"}
@@ -0,0 +1,55 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import { memo, forwardRef, useState } from 'react';
import { useComposedRefs, Field, TextInput } from '@strapi/design-system';
import { Eye, EyeStriked } from '@strapi/icons';
import { useIntl } from 'react-intl';
import { useFocusInputField } from '../../hooks/useFocusInputField.mjs';
import { useField } from '../Form.mjs';
const PasswordInput = /*#__PURE__*/ forwardRef(({ name, required, label, hint, labelAction, ...props }, ref)=>{
const [showPassword, setShowPassword] = useState(false);
const { formatMessage } = useIntl();
const field = useField(name);
const fieldRef = useFocusInputField(name);
const composedRefs = useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxs(Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsx(Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsx(TextInput, {
ref: composedRefs,
autoComplete: "password",
endAction: /*#__PURE__*/ jsx(Field.Action, {
label: formatMessage({
id: 'Auth.form.password.show-password',
defaultMessage: 'Show password'
}),
onClick: ()=>{
setShowPassword((prev)=>!prev);
},
children: showPassword ? /*#__PURE__*/ jsx(Eye, {
fill: "neutral500"
}) : /*#__PURE__*/ jsx(EyeStriked, {
fill: "neutral500"
})
}),
onChange: field.onChange,
value: field.value,
...props,
type: showPassword ? 'text' : 'password'
}),
/*#__PURE__*/ jsx(Field.Hint, {}),
/*#__PURE__*/ jsx(Field.Error, {})
]
});
});
const MemoizedPasswordInput = /*#__PURE__*/ memo(PasswordInput);
export { MemoizedPasswordInput as PasswordInput };
//# sourceMappingURL=Password.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"Password.mjs","sources":["../../../../../../admin/src/components/FormInputs/Password.tsx"],"sourcesContent":["import { forwardRef, memo, useState } from 'react';\n\nimport { TextInput, useComposedRefs, Field } from '@strapi/design-system';\nimport { Eye, EyeStriked } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport type { StringProps } from './types';\n\nconst PasswordInput = forwardRef<HTMLInputElement, StringProps>(\n ({ name, required, label, hint, labelAction, ...props }, ref) => {\n const [showPassword, setShowPassword] = useState(false);\n const { formatMessage } = useIntl();\n const field = useField(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <TextInput\n ref={composedRefs}\n autoComplete=\"password\"\n endAction={\n <Field.Action\n label={formatMessage({\n id: 'Auth.form.password.show-password',\n defaultMessage: 'Show password',\n })}\n onClick={() => {\n setShowPassword((prev) => !prev);\n }}\n >\n {showPassword ? <Eye fill=\"neutral500\" /> : <EyeStriked fill=\"neutral500\" />}\n </Field.Action>\n }\n onChange={field.onChange}\n value={field.value}\n {...props}\n type={showPassword ? 'text' : 'password'}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedPasswordInput = memo(PasswordInput);\n\nexport { MemoizedPasswordInput as PasswordInput };\n"],"names":["PasswordInput","forwardRef","name","required","label","hint","labelAction","props","ref","showPassword","setShowPassword","useState","formatMessage","useIntl","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Label","action","TextInput","autoComplete","endAction","Action","id","defaultMessage","onClick","prev","Eye","fill","EyeStriked","onChange","value","type","Hint","Error","MemoizedPasswordInput","memo"],"mappings":";;;;;;;;AAWA,MAAMA,8BAAgBC,UACpB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;AACvD,IAAA,MAAM,CAACC,YAAAA,EAAcC,eAAgB,CAAA,GAAGC,QAAS,CAAA,KAAA,CAAA;IACjD,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAC1B,IAAA,MAAMC,QAAQC,QAASb,CAAAA,IAAAA,CAAAA;AACvB,IAAA,MAAMc,WAAWC,kBAAqCf,CAAAA,IAAAA,CAAAA;IAEtD,MAAMgB,YAAAA,GAAeC,gBAAgBX,GAAKQ,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,IAAA,CAACC,MAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAErB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAqB,GAAA,CAACH,MAAMI,KAAK,EAAA;gBAACC,MAAQpB,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCoB,GAACG,CAAAA,SAAAA,EAAAA;gBACCnB,GAAKU,EAAAA,YAAAA;gBACLU,YAAa,EAAA,UAAA;gBACbC,SACE,gBAAAL,GAAA,CAACH,MAAMS,MAAM,EAAA;AACX1B,oBAAAA,KAAAA,EAAOQ,aAAc,CAAA;wBACnBmB,EAAI,EAAA,kCAAA;wBACJC,cAAgB,EAAA;AAClB,qBAAA,CAAA;oBACAC,OAAS,EAAA,IAAA;wBACPvB,eAAgB,CAAA,CAACwB,OAAS,CAACA,IAAAA,CAAAA;AAC7B,qBAAA;AAECzB,oBAAAA,QAAAA,EAAAA,YAAAA,iBAAee,GAACW,CAAAA,GAAAA,EAAAA;wBAAIC,IAAK,EAAA;uCAAkBZ,GAACa,CAAAA,UAAAA,EAAAA;wBAAWD,IAAK,EAAA;;;AAGjEE,gBAAAA,QAAAA,EAAUxB,MAAMwB,QAAQ;AACxBC,gBAAAA,KAAAA,EAAOzB,MAAMyB,KAAK;AACjB,gBAAA,GAAGhC,KAAK;AACTiC,gBAAAA,IAAAA,EAAM/B,eAAe,MAAS,GAAA;;AAEhC,0BAAAe,GAAA,CAACH,MAAMoB,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAjB,GAAA,CAACH,MAAMqB,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,sCAAwBC,IAAK5C,CAAAA,aAAAA;;;;"}
@@ -0,0 +1,133 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var useFocusInputField = require('../../hooks/useFocusInputField.js');
var Form = require('../Form.js');
var Boolean = require('./Boolean.js');
var Checkbox = require('./Checkbox.js');
var Date = require('./Date.js');
var DateTime = require('./DateTime.js');
var Email = require('./Email.js');
var Enumeration = require('./Enumeration.js');
var Json = require('./Json.js');
var Number = require('./Number.js');
var Password = require('./Password.js');
var String = require('./String.js');
var Textarea = require('./Textarea.js');
var Time = require('./Time.js');
/* -------------------------------------------------------------------------------------------------
* InputRenderer
* -----------------------------------------------------------------------------------------------*/ /**
* @internal This needs to be tested before being exposed as a public API.
* @experimental
* @description A generic form renderer for Strapi forms. Similar to GenericInputs but with a different API.
* The entire component is memoized to avoid re-renders in large forms.
*/ const InputRenderer = /*#__PURE__*/ React.memo(/*#__PURE__*/ React.forwardRef((props, forwardRef)=>{
switch(props.type){
case 'biginteger':
case 'timestamp':
case 'string':
case 'uid':
return /*#__PURE__*/ jsxRuntime.jsx(String.StringInput, {
ref: forwardRef,
...props
});
case 'boolean':
return /*#__PURE__*/ jsxRuntime.jsx(Boolean.BooleanInput, {
ref: forwardRef,
...props
});
case 'checkbox':
return /*#__PURE__*/ jsxRuntime.jsx(Checkbox.CheckboxInput, {
ref: forwardRef,
...props
});
case 'datetime':
return /*#__PURE__*/ jsxRuntime.jsx(DateTime.DateTimeInput, {
ref: forwardRef,
...props
});
case 'date':
return /*#__PURE__*/ jsxRuntime.jsx(Date.DateInput, {
ref: forwardRef,
...props
});
case 'decimal':
case 'float':
case 'integer':
return /*#__PURE__*/ jsxRuntime.jsx(Number.NumberInput, {
ref: forwardRef,
...props
});
case 'json':
return /*#__PURE__*/ jsxRuntime.jsx(Json.JsonInput, {
ref: forwardRef,
...props
});
case 'email':
return /*#__PURE__*/ jsxRuntime.jsx(Email.EmailInput, {
ref: forwardRef,
...props
});
case 'enumeration':
return /*#__PURE__*/ jsxRuntime.jsx(Enumeration.EnumerationInput, {
ref: forwardRef,
...props
});
case 'password':
return /*#__PURE__*/ jsxRuntime.jsx(Password.PasswordInput, {
ref: forwardRef,
...props
});
case 'text':
return /*#__PURE__*/ jsxRuntime.jsx(Textarea.TextareaInput, {
ref: forwardRef,
...props
});
case 'time':
return /*#__PURE__*/ jsxRuntime.jsx(Time.TimeInput, {
ref: forwardRef,
...props
});
default:
// This is cast because this renderer tackles all the possibilities of the InputProps, but this is for runtime catches.
return /*#__PURE__*/ jsxRuntime.jsx(NotSupportedField, {
ref: forwardRef,
...props
});
}
}));
const NotSupportedField = /*#__PURE__*/ React.forwardRef(({ label, hint, name, required, type, labelAction }, ref)=>{
const { error } = Form.useField(name);
const fieldRef = useFocusInputField.useFocusInputField(name);
const composedRefs = designSystem.useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
error: error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.TextInput, {
ref: composedRefs,
disabled: true,
placeholder: `Unsupported field type: ${type}`,
required: required,
type: "text",
value: ""
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Hint, {}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
});
});
const MemoizedInputRenderer = /*#__PURE__*/ React.memo(InputRenderer);
exports.InputRenderer = MemoizedInputRenderer;
//# sourceMappingURL=Renderer.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Renderer.js","sources":["../../../../../../admin/src/components/FormInputs/Renderer.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { TextInput, useComposedRefs, Field } from '@strapi/design-system';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { BooleanInput } from './Boolean';\nimport { CheckboxInput } from './Checkbox';\nimport { DateInput } from './Date';\nimport { DateTimeInput } from './DateTime';\nimport { EmailInput } from './Email';\nimport { EnumerationInput } from './Enumeration';\nimport { JsonInput } from './Json';\nimport { NumberInput } from './Number';\nimport { PasswordInput } from './Password';\nimport { StringInput } from './String';\nimport { TextareaInput } from './Textarea';\nimport { TimeInput } from './Time';\n\nimport type { InputProps } from '../Form';\n\n/* -------------------------------------------------------------------------------------------------\n * InputRenderer\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * @internal This needs to be tested before being exposed as a public API.\n * @experimental\n * @description A generic form renderer for Strapi forms. Similar to GenericInputs but with a different API.\n * The entire component is memoized to avoid re-renders in large forms.\n */\nconst InputRenderer = memo(\n forwardRef<any, InputProps>((props, forwardRef) => {\n switch (props.type) {\n case 'biginteger':\n case 'timestamp':\n case 'string':\n case 'uid':\n return <StringInput ref={forwardRef} {...props} />;\n case 'boolean':\n return <BooleanInput ref={forwardRef} {...props} />;\n case 'checkbox':\n return <CheckboxInput ref={forwardRef} {...props} />;\n case 'datetime':\n return <DateTimeInput ref={forwardRef} {...props} />;\n case 'date':\n return <DateInput ref={forwardRef} {...props} />;\n case 'decimal':\n case 'float':\n case 'integer':\n return <NumberInput ref={forwardRef} {...props} />;\n case 'json':\n return <JsonInput ref={forwardRef} {...props} />;\n case 'email':\n return <EmailInput ref={forwardRef} {...props} />;\n case 'enumeration':\n return <EnumerationInput ref={forwardRef} {...props} />;\n case 'password':\n return <PasswordInput ref={forwardRef} {...props} />;\n case 'text':\n return <TextareaInput ref={forwardRef} {...props} />;\n case 'time':\n return <TimeInput ref={forwardRef} {...props} />;\n default:\n // This is cast because this renderer tackles all the possibilities of the InputProps, but this is for runtime catches.\n return <NotSupportedField ref={forwardRef} {...(props as InputProps)} />;\n }\n })\n);\n\nconst NotSupportedField = forwardRef<any, InputProps>(\n ({ label, hint, name, required, type, labelAction }, ref) => {\n const { error } = useField(name);\n const fieldRef = useFocusInputField(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <TextInput\n ref={composedRefs}\n disabled\n placeholder={`Unsupported field type: ${type}`}\n required={required}\n type=\"text\"\n value=\"\"\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedInputRenderer = memo(InputRenderer);\n\nexport { MemoizedInputRenderer as InputRenderer };\n"],"names":["InputRenderer","memo","forwardRef","props","type","_jsx","StringInput","ref","BooleanInput","CheckboxInput","DateTimeInput","DateInput","NumberInput","JsonInput","EmailInput","EnumerationInput","PasswordInput","TextareaInput","TimeInput","NotSupportedField","label","hint","name","required","labelAction","error","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","Label","action","TextInput","disabled","placeholder","value","Hint","Error","MemoizedInputRenderer"],"mappings":";;;;;;;;;;;;;;;;;;;;AAsBA;;;;;;;AASC,IACD,MAAMA,aAAAA,iBAAgBC,UACpBC,eAAAA,gBAAAA,CAA4B,CAACC,KAAOD,EAAAA,UAAAA,GAAAA;AAClC,IAAA,OAAQC,MAAMC,IAAI;QAChB,KAAK,YAAA;QACL,KAAK,WAAA;QACL,KAAK,QAAA;QACL,KAAK,KAAA;AACH,YAAA,qBAAOC,cAACC,CAAAA,kBAAAA,EAAAA;gBAAYC,GAAKL,EAAAA,UAAAA;AAAa,gBAAA,GAAGC;;QAC3C,KAAK,SAAA;AACH,YAAA,qBAAOE,cAACG,CAAAA,oBAAAA,EAAAA;gBAAaD,GAAKL,EAAAA,UAAAA;AAAa,gBAAA,GAAGC;;QAC5C,KAAK,UAAA;AACH,YAAA,qBAAOE,cAACI,CAAAA,sBAAAA,EAAAA;gBAAcF,GAAKL,EAAAA,UAAAA;AAAa,gBAAA,GAAGC;;QAC7C,KAAK,UAAA;AACH,YAAA,qBAAOE,cAACK,CAAAA,sBAAAA,EAAAA;gBAAcH,GAAKL,EAAAA,UAAAA;AAAa,gBAAA,GAAGC;;QAC7C,KAAK,MAAA;AACH,YAAA,qBAAOE,cAACM,CAAAA,cAAAA,EAAAA;gBAAUJ,GAAKL,EAAAA,UAAAA;AAAa,gBAAA,GAAGC;;QACzC,KAAK,SAAA;Line truncated
@@ -0,0 +1,131 @@
import { jsx, jsxs } from 'react/jsx-runtime';
import { memo, forwardRef } from 'react';
import { useComposedRefs, Field, TextInput } from '@strapi/design-system';
import { useFocusInputField } from '../../hooks/useFocusInputField.mjs';
import { useField } from '../Form.mjs';
import { BooleanInput as MemoizedBooleanInput } from './Boolean.mjs';
import { CheckboxInput as MemoizedCheckboxInput } from './Checkbox.mjs';
import { DateInput as MemoizedDateInput } from './Date.mjs';
import { DateTimeInput as MemoizedDateTimeInput } from './DateTime.mjs';
import { EmailInput as MemoizedEmailInput } from './Email.mjs';
import { EnumerationInput as MemoizedEnumerationInput } from './Enumeration.mjs';
import { JsonInput as MemoizedJsonInput } from './Json.mjs';
import { NumberInput as MemoizedNumberInput } from './Number.mjs';
import { PasswordInput as MemoizedPasswordInput } from './Password.mjs';
import { StringInput as MemoizedStringInput } from './String.mjs';
import { TextareaInput as MemoizedTextareaInput } from './Textarea.mjs';
import { TimeInput as MemoizedTimeInput } from './Time.mjs';
/* -------------------------------------------------------------------------------------------------
* InputRenderer
* -----------------------------------------------------------------------------------------------*/ /**
* @internal This needs to be tested before being exposed as a public API.
* @experimental
* @description A generic form renderer for Strapi forms. Similar to GenericInputs but with a different API.
* The entire component is memoized to avoid re-renders in large forms.
*/ const InputRenderer = /*#__PURE__*/ memo(/*#__PURE__*/ forwardRef((props, forwardRef)=>{
switch(props.type){
case 'biginteger':
case 'timestamp':
case 'string':
case 'uid':
return /*#__PURE__*/ jsx(MemoizedStringInput, {
ref: forwardRef,
...props
});
case 'boolean':
return /*#__PURE__*/ jsx(MemoizedBooleanInput, {
ref: forwardRef,
...props
});
case 'checkbox':
return /*#__PURE__*/ jsx(MemoizedCheckboxInput, {
ref: forwardRef,
...props
});
case 'datetime':
return /*#__PURE__*/ jsx(MemoizedDateTimeInput, {
ref: forwardRef,
...props
});
case 'date':
return /*#__PURE__*/ jsx(MemoizedDateInput, {
ref: forwardRef,
...props
});
case 'decimal':
case 'float':
case 'integer':
return /*#__PURE__*/ jsx(MemoizedNumberInput, {
ref: forwardRef,
...props
});
case 'json':
return /*#__PURE__*/ jsx(MemoizedJsonInput, {
ref: forwardRef,
...props
});
case 'email':
return /*#__PURE__*/ jsx(MemoizedEmailInput, {
ref: forwardRef,
...props
});
case 'enumeration':
return /*#__PURE__*/ jsx(MemoizedEnumerationInput, {
ref: forwardRef,
...props
});
case 'password':
return /*#__PURE__*/ jsx(MemoizedPasswordInput, {
ref: forwardRef,
...props
});
case 'text':
return /*#__PURE__*/ jsx(MemoizedTextareaInput, {
ref: forwardRef,
...props
});
case 'time':
return /*#__PURE__*/ jsx(MemoizedTimeInput, {
ref: forwardRef,
...props
});
default:
// This is cast because this renderer tackles all the possibilities of the InputProps, but this is for runtime catches.
return /*#__PURE__*/ jsx(NotSupportedField, {
ref: forwardRef,
...props
});
}
}));
const NotSupportedField = /*#__PURE__*/ forwardRef(({ label, hint, name, required, type, labelAction }, ref)=>{
const { error } = useField(name);
const fieldRef = useFocusInputField(name);
const composedRefs = useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxs(Field.Root, {
error: error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsx(Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsx(TextInput, {
ref: composedRefs,
disabled: true,
placeholder: `Unsupported field type: ${type}`,
required: required,
type: "text",
value: ""
}),
/*#__PURE__*/ jsx(Field.Hint, {}),
/*#__PURE__*/ jsx(Field.Error, {})
]
});
});
const MemoizedInputRenderer = /*#__PURE__*/ memo(InputRenderer);
export { MemoizedInputRenderer as InputRenderer };
//# sourceMappingURL=Renderer.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"Renderer.mjs","sources":["../../../../../../admin/src/components/FormInputs/Renderer.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { TextInput, useComposedRefs, Field } from '@strapi/design-system';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { BooleanInput } from './Boolean';\nimport { CheckboxInput } from './Checkbox';\nimport { DateInput } from './Date';\nimport { DateTimeInput } from './DateTime';\nimport { EmailInput } from './Email';\nimport { EnumerationInput } from './Enumeration';\nimport { JsonInput } from './Json';\nimport { NumberInput } from './Number';\nimport { PasswordInput } from './Password';\nimport { StringInput } from './String';\nimport { TextareaInput } from './Textarea';\nimport { TimeInput } from './Time';\n\nimport type { InputProps } from '../Form';\n\n/* -------------------------------------------------------------------------------------------------\n * InputRenderer\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * @internal This needs to be tested before being exposed as a public API.\n * @experimental\n * @description A generic form renderer for Strapi forms. Similar to GenericInputs but with a different API.\n * The entire component is memoized to avoid re-renders in large forms.\n */\nconst InputRenderer = memo(\n forwardRef<any, InputProps>((props, forwardRef) => {\n switch (props.type) {\n case 'biginteger':\n case 'timestamp':\n case 'string':\n case 'uid':\n return <StringInput ref={forwardRef} {...props} />;\n case 'boolean':\n return <BooleanInput ref={forwardRef} {...props} />;\n case 'checkbox':\n return <CheckboxInput ref={forwardRef} {...props} />;\n case 'datetime':\n return <DateTimeInput ref={forwardRef} {...props} />;\n case 'date':\n return <DateInput ref={forwardRef} {...props} />;\n case 'decimal':\n case 'float':\n case 'integer':\n return <NumberInput ref={forwardRef} {...props} />;\n case 'json':\n return <JsonInput ref={forwardRef} {...props} />;\n case 'email':\n return <EmailInput ref={forwardRef} {...props} />;\n case 'enumeration':\n return <EnumerationInput ref={forwardRef} {...props} />;\n case 'password':\n return <PasswordInput ref={forwardRef} {...props} />;\n case 'text':\n return <TextareaInput ref={forwardRef} {...props} />;\n case 'time':\n return <TimeInput ref={forwardRef} {...props} />;\n default:\n // This is cast because this renderer tackles all the possibilities of the InputProps, but this is for runtime catches.\n return <NotSupportedField ref={forwardRef} {...(props as InputProps)} />;\n }\n })\n);\n\nconst NotSupportedField = forwardRef<any, InputProps>(\n ({ label, hint, name, required, type, labelAction }, ref) => {\n const { error } = useField(name);\n const fieldRef = useFocusInputField(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <TextInput\n ref={composedRefs}\n disabled\n placeholder={`Unsupported field type: ${type}`}\n required={required}\n type=\"text\"\n value=\"\"\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedInputRenderer = memo(InputRenderer);\n\nexport { MemoizedInputRenderer as InputRenderer };\n"],"names":["InputRenderer","memo","forwardRef","props","type","_jsx","StringInput","ref","BooleanInput","CheckboxInput","DateTimeInput","DateInput","NumberInput","JsonInput","EmailInput","EnumerationInput","PasswordInput","TextareaInput","TimeInput","NotSupportedField","label","hint","name","required","labelAction","error","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","Label","action","TextInput","disabled","placeholder","value","Hint","Error","MemoizedInputRenderer"],"mappings":";;;;;;;;;;;;;;;;;;AAsBA;;;;;;;AASC,IACD,MAAMA,aAAAA,iBAAgBC,IACpBC,eAAAA,UAAAA,CAA4B,CAACC,KAAOD,EAAAA,UAAAA,GAAAA;AAClC,IAAA,OAAQC,MAAMC,IAAI;QAChB,KAAK,YAAA;QACL,KAAK,WAAA;QACL,KAAK,QAAA;QACL,KAAK,KAAA;AACH,YAAA,qBAAOC,GAACC,CAAAA,mBAAAA,EAAAA;gBAAYC,GAAKL,EAAAA,UAAAA;AAAa,gBAAA,GAAGC;;QAC3C,KAAK,SAAA;AACH,YAAA,qBAAOE,GAACG,CAAAA,oBAAAA,EAAAA;gBAAaD,GAAKL,EAAAA,UAAAA;AAAa,gBAAA,GAAGC;;QAC5C,KAAK,UAAA;AACH,YAAA,qBAAOE,GAACI,CAAAA,qBAAAA,EAAAA;gBAAcF,GAAKL,EAAAA,UAAAA;AAAa,gBAAA,GAAGC;;QAC7C,KAAK,UAAA;AACH,YAAA,qBAAOE,GAACK,CAAAA,qBAAAA,EAAAA;gBAAcH,GAAKL,EAAAA,UAAAA;AAAa,gBAAA,GAAGC;;QAC7C,KAAK,MAAA;AACH,YAAA,qBAAOE,GAACM,CAAAA,iBAAAA,EAAAA;gBAAUJ,GAAKL,EAAAA,UAAAA;AAAa,gBAAA,GAAGC;;QACzC,KAAK,SAAA;QLine truncated
@@ -0,0 +1,37 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var useFocusInputField = require('../../hooks/useFocusInputField.js');
var Form = require('../Form.js');
const StringInput = /*#__PURE__*/ React.forwardRef(({ name, required, label, hint, labelAction, ...props }, ref)=>{
const field = Form.useField(name);
const fieldRef = useFocusInputField.useFocusInputField(name);
const composedRefs = designSystem.useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.TextInput, {
ref: composedRefs,
onChange: field.onChange,
value: field.value ?? '',
...props
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Hint, {}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
});
});
const MemoizedStringInput = /*#__PURE__*/ React.memo(StringInput);
exports.StringInput = MemoizedStringInput;
//# sourceMappingURL=String.js.map
@@ -0,0 +1 @@
{"version":3,"file":"String.js","sources":["../../../../../../admin/src/components/FormInputs/String.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { TextInput, useComposedRefs, Field } from '@strapi/design-system';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { type InputProps, useField } from '../Form';\n\nconst StringInput = forwardRef<HTMLInputElement, InputProps>(\n ({ name, required, label, hint, labelAction, ...props }, ref) => {\n const field = useField(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <TextInput\n ref={composedRefs}\n onChange={field.onChange}\n value={field.value ?? ''}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedStringInput = memo(StringInput);\n\nexport { MemoizedStringInput as StringInput };\n"],"names":["StringInput","forwardRef","name","required","label","hint","labelAction","props","ref","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Label","action","TextInput","onChange","value","Hint","Error","MemoizedStringInput","memo"],"mappings":";;;;;;;;AAOA,MAAMA,4BAAcC,gBAClB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;AACvD,IAAA,MAAMC,QAAQC,aAASR,CAAAA,IAAAA,CAAAA;AACvB,IAAA,MAAMS,WAAWC,qCAAqCV,CAAAA,IAAAA,CAAAA;IAEtD,MAAMW,YAAAA,GAAeC,6BAAgBN,GAAKG,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,eAAA,CAACC,mBAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAEhB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAgB,cAAA,CAACH,mBAAMI,KAAK,EAAA;gBAACC,MAAQf,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCe,cAACG,CAAAA,sBAAAA,EAAAA;gBACCd,GAAKK,EAAAA,YAAAA;AACLU,gBAAAA,QAAAA,EAAUd,MAAMc,QAAQ;gBACxBC,KAAOf,EAAAA,KAAAA,CAAMe,KAAK,IAAI,EAAA;AACrB,gBAAA,GAAGjB;;AAEN,0BAAAY,cAAA,CAACH,mBAAMS,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAN,cAAA,CAACH,mBAAMU,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,oCAAsBC,UAAK5B,CAAAA,WAAAA;;;;"}
@@ -0,0 +1,35 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import { memo, forwardRef } from 'react';
import { useComposedRefs, Field, TextInput } from '@strapi/design-system';
import { useFocusInputField } from '../../hooks/useFocusInputField.mjs';
import { useField } from '../Form.mjs';
const StringInput = /*#__PURE__*/ forwardRef(({ name, required, label, hint, labelAction, ...props }, ref)=>{
const field = useField(name);
const fieldRef = useFocusInputField(name);
const composedRefs = useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxs(Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsx(Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsx(TextInput, {
ref: composedRefs,
onChange: field.onChange,
value: field.value ?? '',
...props
}),
/*#__PURE__*/ jsx(Field.Hint, {}),
/*#__PURE__*/ jsx(Field.Error, {})
]
});
});
const MemoizedStringInput = /*#__PURE__*/ memo(StringInput);
export { MemoizedStringInput as StringInput };
//# sourceMappingURL=String.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"String.mjs","sources":["../../../../../../admin/src/components/FormInputs/String.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { TextInput, useComposedRefs, Field } from '@strapi/design-system';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { type InputProps, useField } from '../Form';\n\nconst StringInput = forwardRef<HTMLInputElement, InputProps>(\n ({ name, required, label, hint, labelAction, ...props }, ref) => {\n const field = useField(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <TextInput\n ref={composedRefs}\n onChange={field.onChange}\n value={field.value ?? ''}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedStringInput = memo(StringInput);\n\nexport { MemoizedStringInput as StringInput };\n"],"names":["StringInput","forwardRef","name","required","label","hint","labelAction","props","ref","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Label","action","TextInput","onChange","value","Hint","Error","MemoizedStringInput","memo"],"mappings":";;;;;;AAOA,MAAMA,4BAAcC,UAClB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;AACvD,IAAA,MAAMC,QAAQC,QAASR,CAAAA,IAAAA,CAAAA;AACvB,IAAA,MAAMS,WAAWC,kBAAqCV,CAAAA,IAAAA,CAAAA;IAEtD,MAAMW,YAAAA,GAAeC,gBAAgBN,GAAKG,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,IAAA,CAACC,MAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAEhB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAgB,GAAA,CAACH,MAAMI,KAAK,EAAA;gBAACC,MAAQf,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCe,GAACG,CAAAA,SAAAA,EAAAA;gBACCd,GAAKK,EAAAA,YAAAA;AACLU,gBAAAA,QAAAA,EAAUd,MAAMc,QAAQ;gBACxBC,KAAOf,EAAAA,KAAAA,CAAMe,KAAK,IAAI,EAAA;AACrB,gBAAA,GAAGjB;;AAEN,0BAAAY,GAAA,CAACH,MAAMS,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAN,GAAA,CAACH,MAAMU,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,oCAAsBC,IAAK5B,CAAAA,WAAAA;;;;"}
@@ -0,0 +1,37 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var useFocusInputField = require('../../hooks/useFocusInputField.js');
var Form = require('../Form.js');
const TextareaInput = /*#__PURE__*/ React.forwardRef(({ name, required, label, hint, labelAction, ...props }, ref)=>{
const field = Form.useField(name);
const fieldRef = useFocusInputField.useFocusInputField(name);
const composedRefs = designSystem.useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Textarea, {
ref: composedRefs,
onChange: field.onChange,
value: field.value ?? '',
...props
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Hint, {}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
});
});
const MemoizedTextareaInput = /*#__PURE__*/ React.memo(TextareaInput);
exports.TextareaInput = MemoizedTextareaInput;
//# sourceMappingURL=Textarea.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Textarea.js","sources":["../../../../../../admin/src/components/FormInputs/Textarea.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { Textarea, useComposedRefs, Field } from '@strapi/design-system';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport type { StringProps } from './types';\n\nconst TextareaInput = forwardRef<HTMLTextAreaElement, StringProps>(\n ({ name, required, label, hint, labelAction, ...props }, ref) => {\n const field = useField(name);\n const fieldRef = useFocusInputField<HTMLTextAreaElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <Textarea\n ref={composedRefs}\n onChange={field.onChange}\n value={field.value ?? ''}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedTextareaInput = memo(TextareaInput);\n\nexport { MemoizedTextareaInput as TextareaInput };\n"],"names":["TextareaInput","forwardRef","name","required","label","hint","labelAction","props","ref","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Label","action","Textarea","onChange","value","Hint","Error","MemoizedTextareaInput","memo"],"mappings":";;;;;;;;AASA,MAAMA,8BAAgBC,gBACpB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;AACvD,IAAA,MAAMC,QAAQC,aAASR,CAAAA,IAAAA,CAAAA;AACvB,IAAA,MAAMS,WAAWC,qCAAwCV,CAAAA,IAAAA,CAAAA;IAEzD,MAAMW,YAAAA,GAAeC,6BAAgBN,GAAKG,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,eAAA,CAACC,mBAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAEhB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAgB,cAAA,CAACH,mBAAMI,KAAK,EAAA;gBAACC,MAAQf,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCe,cAACG,CAAAA,qBAAAA,EAAAA;gBACCd,GAAKK,EAAAA,YAAAA;AACLU,gBAAAA,QAAAA,EAAUd,MAAMc,QAAQ;gBACxBC,KAAOf,EAAAA,KAAAA,CAAMe,KAAK,IAAI,EAAA;AACrB,gBAAA,GAAGjB;;AAEN,0BAAAY,cAAA,CAACH,mBAAMS,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAN,cAAA,CAACH,mBAAMU,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,sCAAwBC,UAAK5B,CAAAA,aAAAA;;;;"}
@@ -0,0 +1,35 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import { memo, forwardRef } from 'react';
import { useComposedRefs, Field, Textarea } from '@strapi/design-system';
import { useFocusInputField } from '../../hooks/useFocusInputField.mjs';
import { useField } from '../Form.mjs';
const TextareaInput = /*#__PURE__*/ forwardRef(({ name, required, label, hint, labelAction, ...props }, ref)=>{
const field = useField(name);
const fieldRef = useFocusInputField(name);
const composedRefs = useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxs(Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsx(Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsx(Textarea, {
ref: composedRefs,
onChange: field.onChange,
value: field.value ?? '',
...props
}),
/*#__PURE__*/ jsx(Field.Hint, {}),
/*#__PURE__*/ jsx(Field.Error, {})
]
});
});
const MemoizedTextareaInput = /*#__PURE__*/ memo(TextareaInput);
export { MemoizedTextareaInput as TextareaInput };
//# sourceMappingURL=Textarea.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"Textarea.mjs","sources":["../../../../../../admin/src/components/FormInputs/Textarea.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { Textarea, useComposedRefs, Field } from '@strapi/design-system';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport type { StringProps } from './types';\n\nconst TextareaInput = forwardRef<HTMLTextAreaElement, StringProps>(\n ({ name, required, label, hint, labelAction, ...props }, ref) => {\n const field = useField(name);\n const fieldRef = useFocusInputField<HTMLTextAreaElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <Textarea\n ref={composedRefs}\n onChange={field.onChange}\n value={field.value ?? ''}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedTextareaInput = memo(TextareaInput);\n\nexport { MemoizedTextareaInput as TextareaInput };\n"],"names":["TextareaInput","forwardRef","name","required","label","hint","labelAction","props","ref","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Label","action","Textarea","onChange","value","Hint","Error","MemoizedTextareaInput","memo"],"mappings":";;;;;;AASA,MAAMA,8BAAgBC,UACpB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;AACvD,IAAA,MAAMC,QAAQC,QAASR,CAAAA,IAAAA,CAAAA;AACvB,IAAA,MAAMS,WAAWC,kBAAwCV,CAAAA,IAAAA,CAAAA;IAEzD,MAAMW,YAAAA,GAAeC,gBAAgBN,GAAKG,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,IAAA,CAACC,MAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAEhB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAgB,GAAA,CAACH,MAAMI,KAAK,EAAA;gBAACC,MAAQf,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCe,GAACG,CAAAA,QAAAA,EAAAA;gBACCd,GAAKK,EAAAA,YAAAA;AACLU,gBAAAA,QAAAA,EAAUd,MAAMc,QAAQ;gBACxBC,KAAOf,EAAAA,KAAAA,CAAMe,KAAK,IAAI,EAAA;AACrB,gBAAA,GAAGjB;;AAEN,0BAAAY,GAAA,CAACH,MAAMS,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAN,GAAA,CAACH,MAAMU,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,sCAAwBC,IAAK5B,CAAAA,aAAAA;;;;"}
@@ -0,0 +1,46 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var reactIntl = require('react-intl');
var useFocusInputField = require('../../hooks/useFocusInputField.js');
var Form = require('../Form.js');
const TimeInput = /*#__PURE__*/ React.forwardRef(({ name, required, label, hint, labelAction, ...props }, ref)=>{
const { formatMessage } = reactIntl.useIntl();
const field = Form.useField(name);
const fieldRef = useFocusInputField.useFocusInputField(name);
const composedRefs = designSystem.useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.TimePicker, {
ref: composedRefs,
clearLabel: formatMessage({
id: 'clearLabel',
defaultMessage: 'Clear'
}),
onChange: (time)=>{
field.onChange(name, `${time}:00.000`);
},
onClear: ()=>field.onChange(name, undefined),
value: field.value ?? '',
...props
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Hint, {}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
});
});
const MemoizedTimeInput = /*#__PURE__*/ React.memo(TimeInput);
exports.TimeInput = MemoizedTimeInput;
//# sourceMappingURL=Time.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Time.js","sources":["../../../../../../admin/src/components/FormInputs/Time.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { TimePicker, useComposedRefs, Field } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst TimeInput = forwardRef<HTMLInputElement, InputProps>(\n ({ name, required, label, hint, labelAction, ...props }, ref) => {\n const { formatMessage } = useIntl();\n const field = useField<string>(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <TimePicker\n ref={composedRefs}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n onChange={(time) => {\n field.onChange(name, `${time}:00.000`);\n }}\n onClear={() => field.onChange(name, undefined)}\n value={field.value ?? ''}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedTimeInput = memo(TimeInput);\n\nexport { MemoizedTimeInput as TimeInput };\n"],"names":["TimeInput","forwardRef","name","required","label","hint","labelAction","props","ref","formatMessage","useIntl","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Label","action","TimePicker","clearLabel","id","defaultMessage","onChange","time","onClear","undefined","value","Hint","Error","MemoizedTimeInput","memo"],"mappings":";;;;;;;;;AAUA,MAAMA,0BAAYC,gBAChB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;IACvD,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAMC,QAAQC,aAAiBV,CAAAA,IAAAA,CAAAA;AAC/B,IAAA,MAAMW,WAAWC,qCAAqCZ,CAAAA,IAAAA,CAAAA;IAEtD,MAAMa,YAAAA,GAAeC,6BAAgBR,GAAKK,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,eAAA,CAACC,mBAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAElB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAkB,cAAA,CAACH,mBAAMI,KAAK,EAAA;gBAACC,MAAQjB,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCiB,cAACG,CAAAA,uBAAAA,EAAAA;gBACChB,GAAKO,EAAAA,YAAAA;AACLU,gBAAAA,UAAAA,EAAYhB,aAAc,CAAA;oBAAEiB,EAAI,EAAA,YAAA;oBAAcC,cAAgB,EAAA;AAAQ,iBAAA,CAAA;AACtEC,gBAAAA,QAAAA,EAAU,CAACC,IAAAA,GAAAA;AACTlB,oBAAAA,KAAAA,CAAMiB,QAAQ,CAAC1B,IAAAA,EAAM,CAAC,EAAE2B,IAAAA,CAAK,OAAO,CAAC,CAAA;AACvC,iBAAA;AACAC,gBAAAA,OAAAA,EAAS,IAAMnB,KAAAA,CAAMiB,QAAQ,CAAC1B,IAAM6B,EAAAA,SAAAA,CAAAA;gBACpCC,KAAOrB,EAAAA,KAAAA,CAAMqB,KAAK,IAAI,EAAA;AACrB,gBAAA,GAAGzB;;AAEN,0BAAAc,cAAA,CAACH,mBAAMe,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAZ,cAAA,CAACH,mBAAMgB,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,kCAAoBC,UAAKpC,CAAAA,SAAAA;;;;"}
@@ -0,0 +1,44 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import { memo, forwardRef } from 'react';
import { useComposedRefs, Field, TimePicker } from '@strapi/design-system';
import { useIntl } from 'react-intl';
import { useFocusInputField } from '../../hooks/useFocusInputField.mjs';
import { useField } from '../Form.mjs';
const TimeInput = /*#__PURE__*/ forwardRef(({ name, required, label, hint, labelAction, ...props }, ref)=>{
const { formatMessage } = useIntl();
const field = useField(name);
const fieldRef = useFocusInputField(name);
const composedRefs = useComposedRefs(ref, fieldRef);
return /*#__PURE__*/ jsxs(Field.Root, {
error: field.error,
name: name,
hint: hint,
required: required,
children: [
/*#__PURE__*/ jsx(Field.Label, {
action: labelAction,
children: label
}),
/*#__PURE__*/ jsx(TimePicker, {
ref: composedRefs,
clearLabel: formatMessage({
id: 'clearLabel',
defaultMessage: 'Clear'
}),
onChange: (time)=>{
field.onChange(name, `${time}:00.000`);
},
onClear: ()=>field.onChange(name, undefined),
value: field.value ?? '',
...props
}),
/*#__PURE__*/ jsx(Field.Hint, {}),
/*#__PURE__*/ jsx(Field.Error, {})
]
});
});
const MemoizedTimeInput = /*#__PURE__*/ memo(TimeInput);
export { MemoizedTimeInput as TimeInput };
//# sourceMappingURL=Time.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"Time.mjs","sources":["../../../../../../admin/src/components/FormInputs/Time.tsx"],"sourcesContent":["import { forwardRef, memo } from 'react';\n\nimport { TimePicker, useComposedRefs, Field } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst TimeInput = forwardRef<HTMLInputElement, InputProps>(\n ({ name, required, label, hint, labelAction, ...props }, ref) => {\n const { formatMessage } = useIntl();\n const field = useField<string>(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n\n const composedRefs = useComposedRefs(ref, fieldRef);\n\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <TimePicker\n ref={composedRefs}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n onChange={(time) => {\n field.onChange(name, `${time}:00.000`);\n }}\n onClear={() => field.onChange(name, undefined)}\n value={field.value ?? ''}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\nconst MemoizedTimeInput = memo(TimeInput);\n\nexport { MemoizedTimeInput as TimeInput };\n"],"names":["TimeInput","forwardRef","name","required","label","hint","labelAction","props","ref","formatMessage","useIntl","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","_jsxs","Field","Root","error","_jsx","Label","action","TimePicker","clearLabel","id","defaultMessage","onChange","time","onClear","undefined","value","Hint","Error","MemoizedTimeInput","memo"],"mappings":";;;;;;;AAUA,MAAMA,0BAAYC,UAChB,CAAA,CAAC,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGC,OAAO,EAAEC,GAAAA,GAAAA;IACvD,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAC1B,IAAA,MAAMC,QAAQC,QAAiBV,CAAAA,IAAAA,CAAAA;AAC/B,IAAA,MAAMW,WAAWC,kBAAqCZ,CAAAA,IAAAA,CAAAA;IAEtD,MAAMa,YAAAA,GAAeC,gBAAgBR,GAAKK,EAAAA,QAAAA,CAAAA;IAE1C,qBACEI,IAAA,CAACC,MAAMC,IAAI,EAAA;AAACC,QAAAA,KAAAA,EAAOT,MAAMS,KAAK;QAAElB,IAAMA,EAAAA,IAAAA;QAAMG,IAAMA,EAAAA,IAAAA;QAAMF,QAAUA,EAAAA,QAAAA;;AAChE,0BAAAkB,GAAA,CAACH,MAAMI,KAAK,EAAA;gBAACC,MAAQjB,EAAAA,WAAAA;AAAcF,gBAAAA,QAAAA,EAAAA;;0BACnCiB,GAACG,CAAAA,UAAAA,EAAAA;gBACChB,GAAKO,EAAAA,YAAAA;AACLU,gBAAAA,UAAAA,EAAYhB,aAAc,CAAA;oBAAEiB,EAAI,EAAA,YAAA;oBAAcC,cAAgB,EAAA;AAAQ,iBAAA,CAAA;AACtEC,gBAAAA,QAAAA,EAAU,CAACC,IAAAA,GAAAA;AACTlB,oBAAAA,KAAAA,CAAMiB,QAAQ,CAAC1B,IAAAA,EAAM,CAAC,EAAE2B,IAAAA,CAAK,OAAO,CAAC,CAAA;AACvC,iBAAA;AACAC,gBAAAA,OAAAA,EAAS,IAAMnB,KAAAA,CAAMiB,QAAQ,CAAC1B,IAAM6B,EAAAA,SAAAA,CAAAA;gBACpCC,KAAOrB,EAAAA,KAAAA,CAAMqB,KAAK,IAAI,EAAA;AACrB,gBAAA,GAAGzB;;AAEN,0BAAAc,GAAA,CAACH,MAAMe,IAAI,EAAA,EAAA,CAAA;AACX,0BAAAZ,GAAA,CAACH,MAAMgB,KAAK,EAAA,EAAA;;;AAGlB,CAAA,CAAA;AAGF,MAAMC,kCAAoBC,IAAKpC,CAAAA,SAAAA;;;;"}
@@ -0,0 +1,132 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var reactIntl = require('react-intl');
var reactRouterDom = require('react-router-dom');
var Tracking = require('../../features/Tracking.js');
var constants = require('./constants.js');
var Ornaments = require('./Ornaments.js');
var Provider = require('./Provider.js');
const GuidedTourHomepage = ()=>{
const guidedTourState = Provider.useGuidedTour('GuidedTourHomepage', (state)=>state.guidedTourState);
const setSkipped = Provider.useGuidedTour('GuidedTourHomepage', (state)=>state.setSkipped);
const { formatMessage } = reactIntl.useIntl();
const { trackUsage } = Tracking.useTracking();
const sections = Object.entries(constants.LAYOUT_DATA).map(([key, val])=>({
key: key,
title: val.home.title,
content: /*#__PURE__*/ jsxRuntime.jsx(designSystem.LinkButton, {
onClick: ()=>trackUsage(val.home.trackingEvent),
tag: reactRouterDom.NavLink,
to: val.home.cta.target,
endIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.ArrowRight, {}),
children: formatMessage(val.home.cta.title)
}),
isDone: Object.values(guidedTourState[key]).every((value)=>value === true)
}));
const activeSectionIndex = sections.findIndex((section)=>!section.isDone);
const handleSkip = ()=>{
setSkipped(true);
trackUsage('didSkipGuidedtour');
};
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Box, {
hasRadius: true,
shadow: "tableShadow",
paddingTop: 7,
paddingRight: 4,
paddingLeft: 7,
paddingBottom: 4,
background: "neutral0",
children: [
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
direction: "column",
alignItems: "stretch",
gap: 6,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "beta",
tag: "h2",
children: formatMessage({
id: 'app.components.GuidedTour.title',
defaultMessage: '3 steps to get started'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
children: sections.map((section, index)=>{
const state = getState(activeSectionIndex, index);
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Box, {
children: [
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
minWidth: `3rem`,
marginRight: 5,
children: /*#__PURE__*/ jsxRuntime.jsx(Ornaments.Number, {
state: state,
children: index + 1
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "delta",
tag: "h3",
children: formatMessage(section.title)
})
]
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
alignItems: "flex-start",
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
justifyContent: "center",
minWidth: `3rem`,
marginBottom: 3,
marginTop: 3,
marginRight: 5,
children: index === sections.length - 1 ? null : /*#__PURE__*/ jsxRuntime.jsx(Ornaments.VerticalDivider, {
state: state
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
marginTop: 2,
children: state === constants.STATES.IS_ACTIVE ? section.content : null
})
]
})
]
}, section.key);
})
})
]
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
justifyContent: "flex-end",
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
variant: "tertiary",
onClick: handleSkip,
children: formatMessage({
id: 'app.components.GuidedTour.skip',
defaultMessage: 'Skip the tour'
})
})
})
]
});
};
const getState = (activeSectionIndex, index)=>{
if (activeSectionIndex === -1) {
return constants.STATES.IS_DONE;
}
if (index < activeSectionIndex) {
return constants.STATES.IS_DONE;
}
if (index > activeSectionIndex) {
return constants.STATES.IS_NOT_DONE;
}
return constants.STATES.IS_ACTIVE;
};
exports.GuidedTourHomepage = GuidedTourHomepage;
//# sourceMappingURL=Homepage.js.map
Loaded 100 of 65041 files, more files were not shown because too many files have changed in this diff. Show more