From 3bcb40c5eff7be8606358e033e5c913b12625eb8 Mon Sep 17 00:00:00 2001 From: louiscklaw Date: Fri, 6 Jun 2025 13:44:21 +0800 Subject: [PATCH] update kanban, --- .../components/Board/BoardItem.tsx | 65 +++++++ .../components/Board/ListItem.tsx | 22 +++ .../pages/DemoKanbanBoard/components/Menu.css | 113 +++++++++++ .../pages/DemoKanbanBoard/components/Menu.tsx | 109 +++++++++++ .../src/pages/DemoKanbanBoard/index.tsx | 52 ++--- .../src/pages/DemoKanbanBoard/pages/Add.tsx | 152 +++++++++++++++ .../DemoKanbanBoard/pages/Kanban.module.scss | 180 ++++++++++++++++++ .../pages/DemoKanbanBoard/pages/Kanban.tsx | 158 +++++++++++++++ .../DemoKanbanBoard/store/SettingsStore.ts | 164 ++++++++++++++++ .../src/pages/DemoKanbanBoard/store/index.ts | 2 + .../DemoKanbanBoard/theme/variables.scss | 100 ++++++++++ 11 files changed, 1094 insertions(+), 23 deletions(-) create mode 100644 03_source/mobile/src/pages/DemoKanbanBoard/components/Board/BoardItem.tsx create mode 100644 03_source/mobile/src/pages/DemoKanbanBoard/components/Board/ListItem.tsx create mode 100644 03_source/mobile/src/pages/DemoKanbanBoard/components/Menu.css create mode 100644 03_source/mobile/src/pages/DemoKanbanBoard/components/Menu.tsx create mode 100644 03_source/mobile/src/pages/DemoKanbanBoard/pages/Add.tsx create mode 100644 03_source/mobile/src/pages/DemoKanbanBoard/pages/Kanban.module.scss create mode 100644 03_source/mobile/src/pages/DemoKanbanBoard/pages/Kanban.tsx create mode 100644 03_source/mobile/src/pages/DemoKanbanBoard/store/SettingsStore.ts create mode 100644 03_source/mobile/src/pages/DemoKanbanBoard/store/index.ts create mode 100644 03_source/mobile/src/pages/DemoKanbanBoard/theme/variables.scss diff --git a/03_source/mobile/src/pages/DemoKanbanBoard/components/Board/BoardItem.tsx b/03_source/mobile/src/pages/DemoKanbanBoard/components/Board/BoardItem.tsx new file mode 100644 index 0000000..1882c7b --- /dev/null +++ b/03_source/mobile/src/pages/DemoKanbanBoard/components/Board/BoardItem.tsx @@ -0,0 +1,65 @@ +import { IonBadge, IonIcon, IonItem, IonLabel, IonReorder } from '@ionic/react'; +import { arrowBackOutline, arrowForwardOutline } from 'ionicons/icons'; + +import styles from '../../pages/Kanban.module.scss'; + +export const BoardItem = ({ + id, + item, + index, + type, + moveToggled, + handleMove, +}): React.JSX.Element => ( + +
+
+ +
+

{item.name}

+ + +  {type.name} + +
+

{item.summary}

+
+
+
+ {item.labels.map((label, index2) => { + return ( + + {label} +    + + ); + })} +
+ +
+ {id !== 1 && moveToggled && ( +
handleMove(e, 'Left', id, id - 1, item.id)} + > + +
+ )} + + {id !== 3 && moveToggled && ( +
handleMove(e, 'Right', id, id + 1, item.id)} + > + +
+ )} +
+
+
+); diff --git a/03_source/mobile/src/pages/DemoKanbanBoard/components/Board/ListItem.tsx b/03_source/mobile/src/pages/DemoKanbanBoard/components/Board/ListItem.tsx new file mode 100644 index 0000000..26d895d --- /dev/null +++ b/03_source/mobile/src/pages/DemoKanbanBoard/components/Board/ListItem.tsx @@ -0,0 +1,22 @@ +import { IonIcon, IonItem, IonLabel, IonReorder } from '@ionic/react'; + +import styles from '../../pages/Kanban.module.scss'; + +export const ListItem = ({ id, item, index, type, moveToggled, handleMove }): React.JSX.Element => ( + + +
+ +

{item.name}

+

{item.summary}

+
+ +
+
+
+); diff --git a/03_source/mobile/src/pages/DemoKanbanBoard/components/Menu.css b/03_source/mobile/src/pages/DemoKanbanBoard/components/Menu.css new file mode 100644 index 0000000..0ca47a2 --- /dev/null +++ b/03_source/mobile/src/pages/DemoKanbanBoard/components/Menu.css @@ -0,0 +1,113 @@ +ion-menu ion-content { + --background: var(--ion-item-background, var(--ion-background-color, #fff)); +} + +ion-menu.md ion-content { + --padding-start: 8px; + --padding-end: 8px; + --padding-top: 20px; + --padding-bottom: 20px; +} + +ion-menu.md ion-list { + padding: 20px 0; +} + +ion-menu.md ion-note { + margin-bottom: 30px; +} + +ion-menu.md ion-list-header, ion-menu.md ion-note { + padding-left: 10px; +} + +ion-menu.md ion-list#inbox-list { + border-bottom: 1px solid var(--ion-color-step-150, #d7d8da); +} + +ion-menu.md ion-list#inbox-list ion-list-header { + font-size: 22px; + font-weight: 600; + min-height: 20px; +} + +ion-menu.md ion-list#labels-list ion-list-header { + font-size: 16px; + margin-bottom: 18px; + color: #757575; + min-height: 26px; +} + +ion-menu.md ion-item { + --padding-start: 10px; + --padding-end: 10px; + border-radius: 4px; +} + +ion-menu.md ion-item.selected { + --background: rgba(var(--ion-color-primary-rgb), 0.14); +} + +ion-menu.md ion-item.selected ion-icon { + color: var(--ion-color-primary); +} + +ion-menu.md ion-item ion-icon { + color: #616e7e; +} + +ion-menu.md ion-item ion-label { + font-weight: 500; +} + +ion-menu.ios ion-content { + --padding-bottom: 20px; +} + +ion-menu.ios ion-list { + padding: 20px 0 0 0; +} + +ion-menu.ios ion-note { + line-height: 24px; + margin-bottom: 20px; +} + +ion-menu.ios ion-item { + --padding-start: 16px; + --padding-end: 16px; + --min-height: 50px; +} + +ion-menu.ios ion-item ion-icon { + font-size: 24px; + color: #73849a; +} + +ion-menu.ios ion-item .selected ion-icon { + color: var(--ion-color-primary); +} + +ion-menu.ios ion-list#labels-list ion-list-header { + margin-bottom: 8px; +} + +ion-menu.ios ion-list-header, +ion-menu.ios ion-note { + padding-left: 16px; + padding-right: 16px; +} + +ion-menu.ios ion-note { + margin-bottom: 8px; +} + +ion-note { + display: inline-block; + font-size: 16px; + color: var(--ion-color-medium-shade); +} + +ion-item.selected { + --color: var(--ion-color-primary); +} \ No newline at end of file diff --git a/03_source/mobile/src/pages/DemoKanbanBoard/components/Menu.tsx b/03_source/mobile/src/pages/DemoKanbanBoard/components/Menu.tsx new file mode 100644 index 0000000..7400d03 --- /dev/null +++ b/03_source/mobile/src/pages/DemoKanbanBoard/components/Menu.tsx @@ -0,0 +1,109 @@ +import { + IonContent, + IonIcon, + IonItem, + IonLabel, + IonList, + IonListHeader, + IonMenu, + IonMenuToggle, + IonNote, +} from '@ionic/react'; + +import { useLocation } from 'react-router-dom'; +import { + addOutline, + addSharp, + barChartOutline, + barChartSharp, + bookmarkOutline, + listOutline, + listSharp, +} from 'ionicons/icons'; +import './Menu.css'; + +import { SettingsStore } from '../store'; +import { handleViewChange } from '../store/SettingsStore'; + +const appPages = [ + { + title: 'Add Item', + url: '/page/add/0', + iosIcon: addOutline, + mdIcon: addSharp, + }, +]; + +const actions = [ + { + title: 'Board View', + slug: 'Board', + url: false, + onClick: () => handleViewChange('Board'), + iosIcon: barChartOutline, + mdIcon: barChartSharp, + }, + { + title: 'List View', + slug: 'List', + url: false, + onClick: () => handleViewChange('List'), + iosIcon: listOutline, + mdIcon: listSharp, + }, +]; + +const Menu = (): React.JSX.Element => { + const location = useLocation(); + const view = SettingsStore.useState((s) => s.view); + + return ( + + + + Welcome back + Ionic Kanban Board + {appPages.map((appPage, index) => { + return ( + + + + {appPage.title} + + + ); + })} + + + + Toggle View + View items in list or board view + + {actions.map((action, index) => { + return ( + + + + {action.title} + + + ); + })} + + + + ); +}; + +export default Menu; diff --git a/03_source/mobile/src/pages/DemoKanbanBoard/index.tsx b/03_source/mobile/src/pages/DemoKanbanBoard/index.tsx index b85f50a..b69b165 100644 --- a/03_source/mobile/src/pages/DemoKanbanBoard/index.tsx +++ b/03_source/mobile/src/pages/DemoKanbanBoard/index.tsx @@ -1,38 +1,44 @@ -import { IonIcon, IonLabel, IonRouterOutlet, IonTabBar, IonTabButton, IonTabs } from '@ionic/react'; +import { + IonIcon, + IonLabel, + IonRouterOutlet, + IonSplitPane, + IonTabBar, + IonTabButton, + IonTabs, +} from '@ionic/react'; import { cloudOutline, searchOutline } from 'ionicons/icons'; import { Route, Redirect } from 'react-router'; -import Tab1 from './AppPages/Tab1'; -import Tab2 from './AppPages/Tab2'; +// import Tab1 from './AppPages/Tab1'; +// import Tab2 from './AppPages/Tab2'; -import './style.scss'; +// import './style.scss'; +import './theme/variables.scss'; +import Menu from './components/Menu'; +import Add from './pages/Add'; +import Kanban from './pages/Kanban'; function DemoKanbanBoard() { return ( - - - - - - + + + + + + - + + + + + + + - - {/* */} - - - - Dashboard - - - - Search - - ); } diff --git a/03_source/mobile/src/pages/DemoKanbanBoard/pages/Add.tsx b/03_source/mobile/src/pages/DemoKanbanBoard/pages/Add.tsx new file mode 100644 index 0000000..fd2b994 --- /dev/null +++ b/03_source/mobile/src/pages/DemoKanbanBoard/pages/Add.tsx @@ -0,0 +1,152 @@ +import { + IonButton, + IonButtons, + IonContent, + IonHeader, + IonIcon, + IonInput, + IonItem, + IonLabel, + IonPage, + IonSelect, + IonSelectOption, + IonTextarea, + IonTitle, + IonToolbar, + useIonRouter, +} from '@ionic/react'; +import { checkmarkSharp, chevronBackSharp } from 'ionicons/icons'; +import { useState } from 'react'; +import { useParams } from 'react-router'; +import { SettingsStore } from '../store'; +import { addItem } from '../store/SettingsStore'; + +const Add = (): React.JSX.Element => { + const categories = SettingsStore.useState((s) => s.categories); + const types = SettingsStore.useState((s) => s.types); + const router = useIonRouter(); + const { category_id = false } = useParams(); + + const useFormInput = (initialValue = '') => { + const [value, setValue] = useState(initialValue); + + const onChange = (e) => { + setValue(e.target.value); + }; + + return { + value, + onIonChange: onChange, + }; + }; + + const formFields = [ + { + fields: { + type: 'text', + id: 'name', + placeholder: 'Enter a name...', + }, + state: useFormInput(), + label: 'Name', + options: false, + }, + { + fields: { + type: 'select', + id: 'category_id', + placeholder: 'Select a category', + }, + state: useFormInput(parseInt(category_id)), + label: 'Category', + options: categories, + }, + { + fields: { + type: 'select', + id: 'type_id', + placeholder: 'Select a type...', + }, + state: useFormInput(), + label: 'Type', + options: types, + }, + { + fields: { + type: 'textarea', + id: 'summary', + placeholder: 'Enter a summary...', + }, + state: useFormInput(), + label: 'Summary', + options: false, + }, + ]; + + const add = () => { + const data = []; + + formFields.forEach((field) => { + data[field.fields.id] = field.state.value; + }); + + addItem(data); + router.goBack(); + }; + + return ( + + + + + router.goBack()}> + + + + Add Item + + + + + + + Add Item + + + + {formFields.map((formField, index) => { + const { state, fields, label, options } = formField; + + return ( + + {label} + + {fields.type === 'text' && } + {fields.type === 'textarea' && } + {fields.type === 'select' && ( + + {options.map((option) => { + const optionName = option.name.charAt(0).toUpperCase() + option.name.slice(1); + + return ( + + {optionName} + + ); + })} + + )} + + ); + })} + + + +   Save + + + + ); +}; + +export default Add; diff --git a/03_source/mobile/src/pages/DemoKanbanBoard/pages/Kanban.module.scss b/03_source/mobile/src/pages/DemoKanbanBoard/pages/Kanban.module.scss new file mode 100644 index 0000000..b444de1 --- /dev/null +++ b/03_source/mobile/src/pages/DemoKanbanBoard/pages/Kanban.module.scss @@ -0,0 +1,180 @@ +.categorySlide { + display: flex; + flex-direction: column; +} + +@media only screen and (min-width: 768px) { + .categorySlide { + width: 33%; + } + + .categoryName { + margin-top: 1rem; + width: 92.6% !important; + } +} + +.categoryName { + background-color: #3273ec; + color: white; + width: 100%; + padding: 1rem; + font-size: 1.3rem; + margin-bottom: -0.75rem; +} + +.categoryNameList { + background-color: #3273ec; + color: white; + width: 100%; + padding: 1rem; + font-size: 1.3rem; +} + +.kanbanItemList { + margin: 0rem !important; + border-radius: 0 !important; + border: none !important; + border-bottom: 1px solid rgb(221, 221, 221) !important; +} + +.kanbanItem, +.kanbanItemList { + padding: 1.5rem; + border: 1px solid rgb(221, 221, 221); + border-radius: 5px; + background-color: white; + --background: white; + + .itemTitle { + display: flex; + flex-direction: row; + justify-content: space-between; + align-content: center; + align-items: center; + margin-bottom: 1rem; + + .itemType { + font-size: 0.75rem; + + ion-icon { + font-size: 0.75rem; + padding: 0 !important; + } + } + + h3 { + color: black; + font-weight: 450; + } + } + + .itemTitleList { + display: flex; + flex-direction: row; + justify-content: space-between; + align-content: center; + align-items: center; + margin-bottom: 0rem; + + ion-card-subtitle { + color: black; + margin-top: 0.25rem; + font-size: 0.6rem; + } + } + + .itemList { + display: flex !important; + flex-direction: row !important; + align-content: center; + justify-content: space-between; + align-items: center; + + ion-icon { + font-size: 2rem; + padding-left: 0.5rem; + } + } + + .itemType, + .itemTypeList { + display: flex; + flex-direction: row; + align-content: center; + align-items: center; + justify-content: space-between; + width: fit-content; + } + + .itemTypeList { + margin-right: 0.3rem; + } + + .itemLabels { + margin-top: 1rem; + } + + .itemLabelsList { + margin-top: 0.2rem; + + ion-badge { + font-size: 0.5rem; + } + } + + .itemActions { + display: flex; + flex-direction: row; + justify-content: center; + align-content: center; + align-items: center; + margin-top: 1rem; + + div { + width: 5rem; + background-color: rgb(238, 238, 238); + color: rgb(204, 204, 204); + margin-left: 0.2rem; + margin-right: 0.2rem; + + padding: 0.5rem; + border-radius: 5px; + } + + .moveRight { + text-align: right; + } + + .moveLeft { + text-align: left; + } + } +} + +.itemAdd { + display: flex; + flex-direction: row; + align-content: center; + justify-content: center; + align-items: center; + padding: 1rem; + width: 91.6% !important; + background-color: rgb(241, 241, 241); + color: rgb(179, 179, 179); + border: 2px dashed rgb(216, 216, 216); + border-radius: 5px; + font-size: 1.5rem; + margin-bottom: 2rem; + margin-top: 1rem; +} + +.kanbanItem { + margin: 0 !important; + margin-top: 1rem !important; + --padding: 0 !important; +} + +.listReorder { + padding: 0 !important; +} diff --git a/03_source/mobile/src/pages/DemoKanbanBoard/pages/Kanban.tsx b/03_source/mobile/src/pages/DemoKanbanBoard/pages/Kanban.tsx new file mode 100644 index 0000000..0d56362 --- /dev/null +++ b/03_source/mobile/src/pages/DemoKanbanBoard/pages/Kanban.tsx @@ -0,0 +1,158 @@ +import { + IonButton, + IonButtons, + IonCardSubtitle, + IonContent, + IonHeader, + IonIcon, + IonMenuButton, + IonPage, + IonReorder, + IonReorderGroup, + // TODO: fix missing ionslide in new ionic + // IonSlide, + // IonSlides, + IonTitle, + IonToolbar, + useIonViewDidEnter, +} from '@ionic/react'; +import { addOutline, copyOutline, createOutline } from 'ionicons/icons'; +import React, { useEffect, useState } from 'react'; +import { Link } from 'react-router-dom'; +import { BoardItem } from '../components/Board/BoardItem'; +import { ListItem } from '../components/Board/ListItem'; +import { SettingsStore } from '../store'; + +import styles from './Kanban.module.scss'; + +const Kanban = (): React.JSX.Element => { + return <>// TODO: fix missing ionslide in new ionic; + const view = SettingsStore.useState((s) => s.view); + const categories = SettingsStore.useState((s) => s.categories); + const types = SettingsStore.useState((s) => s.types); + const items = SettingsStore.useState((s) => s.items); + + const [moveToggled, setMoveToggled] = useState(view === 'Board' ? true : false); + const [categoryItems, setCategoryItems] = useState([]); + + useEffect(() => { + setCategoryItems(items); + }, [items]); + + const handleReorder = (e) => { + // In a real world, production app + // In here we could re-arrange and sort array of items + // To be in sync with our state or simply save the new main array + + e.detail.complete(); + }; + + const handleMove = (e, direction, fromCategoryID, toCategoryID, itemID) => { + const fromIndex = categoryItems.findIndex((c) => c.id === fromCategoryID); + const toIndex = categoryItems.findIndex((c) => c.id === toCategoryID); + + const tempCategoryItems = [...categoryItems]; + const itemIndex = categoryItems[fromIndex].items.findIndex((i) => i.id === itemID); + const itemElement = document.querySelector(`#item_${fromCategoryID}_${itemIndex}`); + + const tempItem = { ...categoryItems[fromIndex].items[itemIndex] }; + tempCategoryItems[toIndex].items.push(tempItem); + + itemElement.classList.add(`animate__slideOut${direction}`); + + setTimeout(() => { + itemElement.classList.remove(`animate__slideOut${direction}`); + tempCategoryItems[fromIndex].items.splice(itemIndex, 1); + setCategoryItems(tempCategoryItems); + }, 700); + }; + + useIonViewDidEnter(() => { + document.querySelector('#slider') && document.querySelector('#slider').update(); + }); + + return ( + + + + + + + {view} View + {view === 'Board' && ( + + setMoveToggled(!moveToggled)}> + + + + )} + + + + + + + {view} View + + + + + {categoryItems.map(({ items, id }, index) => { + const name = categories.filter((c) => c.id === id)[0].name; + + return ( + + + {name} ({items.length}) + + + + {items.map((item, index) => { + const type = types.filter((t) => t.id === item.typeID)[0]; + + return ( + + {view === 'Board' && ( + + )} + {view === 'List' && ( + + )} + + ); + })} + + + + + + + ); + })} + + + + ); +}; + +export default Kanban; diff --git a/03_source/mobile/src/pages/DemoKanbanBoard/store/SettingsStore.ts b/03_source/mobile/src/pages/DemoKanbanBoard/store/SettingsStore.ts new file mode 100644 index 0000000..93cd3a6 --- /dev/null +++ b/03_source/mobile/src/pages/DemoKanbanBoard/store/SettingsStore.ts @@ -0,0 +1,164 @@ +import { arrowUpOutline, bugOutline, flashOutline, keyOutline } from 'ionicons/icons'; +import { Store } from 'pullstate'; + +const SettingsStore = new Store({ + view: 'Board', + filter: '', + types: [ + { + id: 1, + name: 'bug', + color: '#ec1111', + icon: bugOutline, + }, + { + id: 2, + name: 'improvement', + color: '#0bbe28', + icon: arrowUpOutline, + }, + { + id: 3, + name: 'enhancement', + color: '#680bbe', + icon: flashOutline, + }, + { + id: 4, + name: 'task', + color: '#0b7ebe', + icon: keyOutline, + }, + ], + categories: [ + { id: 1, name: 'To Do' }, + { id: 2, name: 'In Progress' }, + { id: 3, name: 'Done' }, + ], + items: [ + { + id: 1, + items: [ + { + id: 1, + name: 'Adding projects', + summary: 'Give users the option to add projects and add items to projects', + labels: ['CSS', 'Design', 'Framework'], + typeID: 3, + }, + { + id: 2, + name: 'Add filter by labels', + summary: + 'Add the option to filter items by labels on the board to give the user more control', + labels: ['Filtering', 'Labels'], + typeID: 2, + }, + { + id: 3, + name: "Can't move items after add", + summary: + 'When the user adds a new item, for some reason, it breaks the ability to move items across categories', + labels: ['Move', 'Array', 'Object', 'Broke'], + typeID: 1, + }, + { + id: 4, + name: 'Hook a database up', + summary: 'Link app to a database like MongoDB or Firebase for sync and save', + labels: ['Database', 'MongoDB', 'Firebase'], + typeID: 4, + }, + { + id: 5, + name: 'Add a remove option', + summary: 'Allow the user to remove items from list and board views', + labels: ['Remove', 'Delete', 'Item'], + typeID: 1, + }, + ], + }, + { + id: 2, + items: [ + { + id: 1, + name: 'Add a list view', + summary: 'Allow users to view items on boards in a list view', + labels: ['Kanban', 'List', 'View'], + typeID: 3, + }, + { + id: 2, + name: 'Write some fake tickets', + summary: 'Fill out this app with some fake, real looking tickets', + labels: ['Tickets', 'Todo', 'Items'], + typeID: 4, + }, + ], + }, + { + id: 3, + items: [ + { + id: 1, + name: 'Fix bug with IonSlide', + summary: 'When navigating to the add screen, and coming back, the slides are stuck', + labels: ['Ionic', 'Slides', 'Stuck'], + typeID: 1, + }, + { + id: 2, + name: 'Add slick features', + summary: + 'Add the ability to move cards or items from one category to another, still using IonSlides and IonReorder', + labels: ['Ionic', 'IonSlides', 'IonReorder'], + typeID: 2, + }, + { + id: 3, + name: 'Drag and drop items', + summary: + 'Give the user the ability to drag and drop items while still maintaining click functionality and propagation within the item itself', + labels: ['DND', 'Drag', 'Drop', 'Main feature'], + typeID: 4, + }, + ], + }, + ], +}); + +export default SettingsStore; + +export const addItem = (item) => { + console.log(item); + + SettingsStore.update((s) => { + const tempItems = [...s.items]; + const itemCategoryIndex = tempItems.findIndex( + (t) => parseInt(t.id) === parseInt(item.category_id) + ); + + console.log({ itemCategoryIndex }); + + tempItems[itemCategoryIndex].items.push({ + name: item.name, + summary: item.summary, + typeID: item.type_id, + labels: ['test', 'test1', 'test2', 'test3'], + }); + + s.items = tempItems; + }); +}; + +// export const removeFromCart = coffeeIndex => { + +// SettingsStore.update(s => { s.coffee_ids.splice(coffeeIndex, 1) }); +// } + +export const handleViewChange = (view) => { + SettingsStore.update((s) => { + s.view = view; + }); +}; diff --git a/03_source/mobile/src/pages/DemoKanbanBoard/store/index.ts b/03_source/mobile/src/pages/DemoKanbanBoard/store/index.ts new file mode 100644 index 0000000..358de05 --- /dev/null +++ b/03_source/mobile/src/pages/DemoKanbanBoard/store/index.ts @@ -0,0 +1,2 @@ + +export { default as SettingsStore } from "./SettingsStore"; \ No newline at end of file diff --git a/03_source/mobile/src/pages/DemoKanbanBoard/theme/variables.scss b/03_source/mobile/src/pages/DemoKanbanBoard/theme/variables.scss new file mode 100644 index 0000000..11fac0c --- /dev/null +++ b/03_source/mobile/src/pages/DemoKanbanBoard/theme/variables.scss @@ -0,0 +1,100 @@ +/* +Ionic Variables and Theming. For more info, please see: +http://ionicframework.com/docs/theming/ +*/ + +.demo-kanban-board { + /** Ionic CSS Variables **/ + * { + /** primary **/ + --ion-color-primary: #3880ff; + --ion-color-primary-rgb: 56, 128, 255; + --ion-color-primary-contrast: #ffffff; + --ion-color-primary-contrast-rgb: 255, 255, 255; + --ion-color-primary-shade: #3171e0; + --ion-color-primary-tint: #4c8dff; + + /** secondary **/ + --ion-color-secondary: #3dc2ff; + --ion-color-secondary-rgb: 61, 194, 255; + --ion-color-secondary-contrast: #ffffff; + --ion-color-secondary-contrast-rgb: 255, 255, 255; + --ion-color-secondary-shade: #36abe0; + --ion-color-secondary-tint: #50c8ff; + + /** tertiary **/ + --ion-color-tertiary: #5260ff; + --ion-color-tertiary-rgb: 82, 96, 255; + --ion-color-tertiary-contrast: #ffffff; + --ion-color-tertiary-contrast-rgb: 255, 255, 255; + --ion-color-tertiary-shade: #4854e0; + --ion-color-tertiary-tint: #6370ff; + + /** success **/ + --ion-color-success: #2dd36f; + --ion-color-success-rgb: 45, 211, 111; + --ion-color-success-contrast: #ffffff; + --ion-color-success-contrast-rgb: 255, 255, 255; + --ion-color-success-shade: #28ba62; + --ion-color-success-tint: #42d77d; + + /** warning **/ + --ion-color-warning: #ffc409; + --ion-color-warning-rgb: 255, 196, 9; + --ion-color-warning-contrast: #000000; + --ion-color-warning-contrast-rgb: 0, 0, 0; + --ion-color-warning-shade: #e0ac08; + --ion-color-warning-tint: #ffca22; + + /** danger **/ + --ion-color-danger: #eb445a; + --ion-color-danger-rgb: 235, 68, 90; + --ion-color-danger-contrast: #ffffff; + --ion-color-danger-contrast-rgb: 255, 255, 255; + --ion-color-danger-shade: #cf3c4f; + --ion-color-danger-tint: #ed576b; + + /** dark **/ + --ion-color-dark: #222428; + --ion-color-dark-rgb: 34, 36, 40; + --ion-color-dark-contrast: #ffffff; + --ion-color-dark-contrast-rgb: 255, 255, 255; + --ion-color-dark-shade: #1e2023; + --ion-color-dark-tint: #383a3e; + + /** medium **/ + --ion-color-medium: #92949c; + --ion-color-medium-rgb: 146, 148, 156; + --ion-color-medium-contrast: #ffffff; + --ion-color-medium-contrast-rgb: 255, 255, 255; + --ion-color-medium-shade: #808289; + --ion-color-medium-tint: #9d9fa6; + + /** light **/ + --ion-color-light: #f4f5f8; + --ion-color-light-rgb: 244, 245, 248; + --ion-color-light-contrast: #000000; + --ion-color-light-contrast-rgb: 0, 0, 0; + --ion-color-light-shade: #d7d8da; + --ion-color-light-tint: #f5f6f9; + } + + :root { + --ion-background-color: rgb(241, 241, 241); + } + + ion-badge { + border-radius: 5px; + } + + ion-item.input { + --background: #ffffff !important; + --color: rgb(53, 53, 53) !important; + margin: 1rem; + border-radius: 5px; + } + + ion-reorder-group { + padding: 1rem; + } +}