mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-25 19:48:50 +03:00
Added tabs
This commit is contained in:
parent
0a15a2e1c2
commit
bb244f4407
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
apps/post-analytics-spike/dist/index-7a29597a.mjs.map
vendored
Normal file
1
apps/post-analytics-spike/dist/index-7a29597a.mjs.map
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
||||
import { N as t, j as o } from "./index-052a2715.mjs";
|
||||
import { N as t, j as o } from "./index-7a29597a.mjs";
|
||||
const a = t.create(() => /* @__PURE__ */ o.jsx(o.Fragment, {})), s = { DemoModal: a };
|
||||
export {
|
||||
s as default
|
||||
};
|
||||
//# sourceMappingURL=modals-235335b0.mjs.map
|
||||
//# sourceMappingURL=modals-cffa8516.mjs.map
|
@ -1 +1 @@
|
||||
{"version":3,"file":"modals-235335b0.mjs","sources":["../src/components/DemoModal.tsx","../src/components/modals.tsx"],"sourcesContent":["import NiceModal from '@ebay/nice-modal-react';\n// import {Heading, Modal} from '@tryghost/shade';\n// import {useRouting} from '@tryghost/admin-x-framework/routing';\n\nconst DemoModal = NiceModal.create(() => {\n // const {updateRoute} = useRouting();\n // const modal = NiceModal.useModal();\n\n return ( <></>\n // <Modal\n // afterClose={() => {\n // updateRoute('');\n // }}\n // cancelLabel=''\n // okLabel='Close'\n // size='sm'\n // title='About'\n // onOk={() => {\n // updateRoute('');\n // modal.remove();\n // }}\n // >\n // <div className='mt-3 flex flex-col gap-4'>\n // <p>{`You're looking at a React app inside Ghost Admin. It uses common AdminX framework and Design System packages, and works seamlessly with the current Admin's routing.`}</p>\n // <p>{`At the moment the look and feel follows the current Admin's style to blend in with existing pages. However the system is built in a very flexible way to allow easy updates in the future.`}</p>\n // <Heading className='-mb-2 mt-4' level={5}>Contents</Heading>\n // <p>{`The demo uses a mocked list of members — it's `}<strong>not</strong> {`the actual or future design of members in Ghost Admin. Instead, the pages showcase common design patterns like a list and detail, navigation, modals and toasts.`}</p>\n // </div>\n // </Modal>\n );\n});\n\nexport default DemoModal;\n","import DemoModal from './DemoModal';\nimport {ModalComponent} from '@tryghost/admin-x-framework/routing';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst modals = {DemoModal} satisfies {[key: string]: ModalComponent<any>};\n\nexport default modals;\n\nexport type ModalName = keyof typeof modals;\n"],"names":["DemoModal","NiceModal","jsx","Fragment","modals"],"mappings":";AAIA,MAAMA,IAAYC,EAAU,OAAO,MAIpBC,gBAAAA,EAAA,IAAAC,YAAA,CAAA,CAAA,CAsBd,GC1BKC,IAAS,EAAC,WAAAJ,EAAS;"}
|
||||
{"version":3,"file":"modals-cffa8516.mjs","sources":["../src/components/DemoModal.tsx","../src/components/modals.tsx"],"sourcesContent":["import NiceModal from '@ebay/nice-modal-react';\n// import {Heading, Modal} from '@tryghost/shade';\n// import {useRouting} from '@tryghost/admin-x-framework/routing';\n\nconst DemoModal = NiceModal.create(() => {\n // const {updateRoute} = useRouting();\n // const modal = NiceModal.useModal();\n\n return ( <></>\n // <Modal\n // afterClose={() => {\n // updateRoute('');\n // }}\n // cancelLabel=''\n // okLabel='Close'\n // size='sm'\n // title='About'\n // onOk={() => {\n // updateRoute('');\n // modal.remove();\n // }}\n // >\n // <div className='mt-3 flex flex-col gap-4'>\n // <p>{`You're looking at a React app inside Ghost Admin. It uses common AdminX framework and Design System packages, and works seamlessly with the current Admin's routing.`}</p>\n // <p>{`At the moment the look and feel follows the current Admin's style to blend in with existing pages. However the system is built in a very flexible way to allow easy updates in the future.`}</p>\n // <Heading className='-mb-2 mt-4' level={5}>Contents</Heading>\n // <p>{`The demo uses a mocked list of members — it's `}<strong>not</strong> {`the actual or future design of members in Ghost Admin. Instead, the pages showcase common design patterns like a list and detail, navigation, modals and toasts.`}</p>\n // </div>\n // </Modal>\n );\n});\n\nexport default DemoModal;\n","import DemoModal from './DemoModal';\nimport {ModalComponent} from '@tryghost/admin-x-framework/routing';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst modals = {DemoModal} satisfies {[key: string]: ModalComponent<any>};\n\nexport default modals;\n\nexport type ModalName = keyof typeof modals;\n"],"names":["DemoModal","NiceModal","jsx","Fragment","modals"],"mappings":";AAIA,MAAMA,IAAYC,EAAU,OAAO,MAIpBC,gBAAAA,EAAA,IAAAC,YAAA,CAAA,CAAA,CAsBd,GC1BKC,IAAS,EAAC,WAAAJ,EAAS;"}
|
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
||||
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger, Heading, Icon } from "@tryghost/shade";
|
||||
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger, Heading, Icon, Tabs, TabsContent, TabsList, TabsTrigger } from "@tryghost/shade";
|
||||
|
||||
const PostAnalytics = () => {
|
||||
return (
|
||||
@ -42,9 +42,40 @@ const PostAnalytics = () => {
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div className="mt-8 border rounded-lg border-grey-300 min-h-[500px] flex items-center justify-center text-grey-500">
|
||||
TK
|
||||
</div>
|
||||
<Tabs className="mt-8" defaultValue="overview">
|
||||
<TabsList className="grid w-full grid-cols-5">
|
||||
<TabsTrigger value="overview">
|
||||
Overview
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="email">
|
||||
Email
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="web">
|
||||
Web
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="comments">
|
||||
Comments
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="growth">
|
||||
Growth
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="overview">
|
||||
Overview
|
||||
</TabsContent>
|
||||
<TabsContent value="email">
|
||||
Email
|
||||
</TabsContent>
|
||||
<TabsContent value="web">
|
||||
Web
|
||||
</TabsContent>
|
||||
<TabsContent value="comments">
|
||||
Comments
|
||||
</TabsContent>
|
||||
<TabsContent value="growth">
|
||||
Growth
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -74,7 +74,7 @@
|
||||
"@radix-ui/react-separator": "1.1.0",
|
||||
"@radix-ui/react-slot": "^1.1.0",
|
||||
"@radix-ui/react-switch": "1.1.0",
|
||||
"@radix-ui/react-tabs": "1.1.0",
|
||||
"@radix-ui/react-tabs": "^1.1.1",
|
||||
"@radix-ui/react-tooltip": "1.1.2",
|
||||
"@sentry/react": "7.119.2",
|
||||
"@tailwindcss/forms": "0.5.9",
|
||||
|
36
apps/shade/src/components/ui/tabs.stories.tsx
Normal file
36
apps/shade/src/components/ui/tabs.stories.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
import type {Meta, StoryObj} from '@storybook/react';
|
||||
|
||||
import {
|
||||
Tabs,
|
||||
TabsContent,
|
||||
TabsList,
|
||||
TabsTrigger
|
||||
} from '@/components/ui/tabs';
|
||||
|
||||
const meta = {
|
||||
title: 'Components / Tabs',
|
||||
component: Tabs,
|
||||
tags: ['autodocs']
|
||||
} satisfies Meta<typeof Tabs>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof Tabs>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
children: (
|
||||
<Tabs className="w-[400px]" defaultValue="account">
|
||||
<TabsList className="grid w-full grid-cols-2">
|
||||
<TabsTrigger value="account">Account</TabsTrigger>
|
||||
<TabsTrigger value="password">Password</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="account">
|
||||
Account
|
||||
</TabsContent>
|
||||
<TabsContent value="password">
|
||||
Password
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
)
|
||||
}
|
||||
};
|
53
apps/shade/src/components/ui/tabs.tsx
Normal file
53
apps/shade/src/components/ui/tabs.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
import * as React from 'react';
|
||||
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
||||
|
||||
import {cn} from '@/lib/utils';
|
||||
|
||||
const Tabs = TabsPrimitive.Root;
|
||||
|
||||
const TabsList = React.forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.List>,
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
|
||||
>(({className, ...props}, ref) => (
|
||||
<TabsPrimitive.List
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'inline-flex h-10 items-center justify-center rounded-md bg-neutral-100 p-1 text-neutral-500 dark:bg-neutral-800 dark:text-neutral-400',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
TabsList.displayName = TabsPrimitive.List.displayName;
|
||||
|
||||
const TabsTrigger = React.forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.Trigger>,
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
|
||||
>(({className, ...props}, ref) => (
|
||||
<TabsPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-white transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-white data-[state=active]:text-neutral-950 data-[state=active]:shadow-sm dark:ring-offset-neutral-950 dark:focus-visible:ring-neutral-300 dark:data-[state=active]:bg-neutral-950 dark:data-[state=active]:text-neutral-50',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
||||
|
||||
const TabsContent = React.forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
|
||||
>(({className, ...props}, ref) => (
|
||||
<TabsPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'mt-2 ring-offset-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-950 focus-visible:ring-offset-2 dark:ring-offset-neutral-950 dark:focus-visible:ring-neutral-300',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
||||
|
||||
export {Tabs, TabsList, TabsTrigger, TabsContent};
|
@ -5,6 +5,7 @@ export * from './components/typography/heading';
|
||||
export * from './components/ui/breadcrumb';
|
||||
export * from './components/ui/button';
|
||||
export * from './components/ui/dropdown-menu';
|
||||
export * from './components/ui/tabs';
|
||||
|
||||
export {default as useGlobalDirtyState} from './hooks/useGlobalDirtyState';
|
||||
export {usePagination} from './hooks/usePagination';
|
||||
|
14
yarn.lock
14
yarn.lock
@ -4715,6 +4715,20 @@
|
||||
"@radix-ui/react-roving-focus" "1.1.0"
|
||||
"@radix-ui/react-use-controllable-state" "1.1.0"
|
||||
|
||||
"@radix-ui/react-tabs@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-tabs/-/react-tabs-1.1.1.tgz#698bd97923f6bcd629738198a73beebcc4c88b30"
|
||||
integrity sha512-3GBUDmP2DvzmtYLMsHmpA1GtR46ZDZ+OreXM/N+kkQJOPIgytFWWTfDQmBQKBvaFS0Vno0FktdbVzN28KGrMdw==
|
||||
dependencies:
|
||||
"@radix-ui/primitive" "1.1.0"
|
||||
"@radix-ui/react-context" "1.1.1"
|
||||
"@radix-ui/react-direction" "1.1.0"
|
||||
"@radix-ui/react-id" "1.1.0"
|
||||
"@radix-ui/react-presence" "1.1.1"
|
||||
"@radix-ui/react-primitive" "2.0.0"
|
||||
"@radix-ui/react-roving-focus" "1.1.0"
|
||||
"@radix-ui/react-use-controllable-state" "1.1.0"
|
||||
|
||||
"@radix-ui/react-toggle-group@1.0.4":
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle-group/-/react-toggle-group-1.0.4.tgz#f5b5c8c477831b013bec3580c55e20a68179d6ec"
|
||||
|
Loading…
Reference in New Issue
Block a user