Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .vercelignore
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated this because this rule prevented the images in my assets/ directory from being served on Vercel.

Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
core/src/components/**/*/*.png
# Exclude visual-regression snapshot artifacts only
core/src/**/*-snapshots/*.png
8 changes: 8 additions & 0 deletions core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,14 @@ ion-footer,prop,mode,"ios" | "md",undefined,false,false
ion-footer,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-footer,prop,translucent,boolean,false,false,false

ion-gallery,shadow
ion-gallery,prop,columns,GalleryBreakpointColumns | number | string,DEFAULT_COLUMNS,false,false
ion-gallery,prop,layout,"masonry" | "uniform",'uniform',false,true
ion-gallery,prop,mode,"ios" | "md",undefined,false,false
ion-gallery,prop,order,"best-fit" | "sequential",'sequential',false,true
ion-gallery,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-gallery,css-prop,--ion-gallery-gap

ion-grid,shadow
ion-grid,prop,fixed,boolean,false,false,false
ion-grid,prop,mode,"ios" | "md",undefined,false,false
Expand Down
66 changes: 66 additions & 0 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { BreadcrumbCollapsedClickEventDetail } from "./components/breadcrumb/bre
import { CheckboxChangeEventDetail } from "./components/checkbox/checkbox-interface";
import { ScrollBaseDetail, ScrollDetail } from "./components/content/content-interface";
import { DatetimeChangeEventDetail, DatetimeHighlight, DatetimeHighlightCallback, DatetimeHourCycle, DatetimePresentation, FormatOptions, TitleSelectedDatesFormatter } from "./components/datetime/datetime-interface";
import { GalleryColumns } from "./components/gallery/gallery-interface";
import { SpinnerTypes } from "./components/spinner/spinner-configs";
import { InputChangeEventDetail, InputInputEventDetail } from "./components/input/input-interface";
import { InputOtpChangeEventDetail, InputOtpCompleteEventDetail, InputOtpInputEventDetail } from "./components/input-otp/input-otp-interface";
Expand Down Expand Up @@ -54,6 +55,7 @@ export { BreadcrumbCollapsedClickEventDetail } from "./components/breadcrumb/bre
export { CheckboxChangeEventDetail } from "./components/checkbox/checkbox-interface";
export { ScrollBaseDetail, ScrollDetail } from "./components/content/content-interface";
export { DatetimeChangeEventDetail, DatetimeHighlight, DatetimeHighlightCallback, DatetimeHourCycle, DatetimePresentation, FormatOptions, TitleSelectedDatesFormatter } from "./components/datetime/datetime-interface";
export { GalleryColumns } from "./components/gallery/gallery-interface";
export { SpinnerTypes } from "./components/spinner/spinner-configs";
export { InputChangeEventDetail, InputInputEventDetail } from "./components/input/input-interface";
export { InputOtpChangeEventDetail, InputOtpCompleteEventDetail, InputOtpInputEventDetail } from "./components/input-otp/input-otp-interface";
Expand Down Expand Up @@ -1469,6 +1471,31 @@ export namespace Components {
*/
"translucent": boolean;
}
interface IonGallery {
/**
* The number of columns to display. Can be set as a number or an object of breakpoint values (e.g. `{ xs: 2, sm: 3, md: 4 }`).
* @default DEFAULT_COLUMNS
*/
"columns": GalleryColumns;
/**
* The visual layout of the gallery. When `uniform`, rows take up the height of the tallest item and are spaced evenly across the gallery. Additionally, items will have an aspect ratio of 1/1, forcing them to be square unless a height is explicitly set. When `masonry`, items will be positioned under each other with only the specified gap between them.
* @default 'uniform'
*/
"layout": 'uniform' | 'masonry';
/**
* The mode determines the platform behaviors of the component.
*/
"mode"?: "ios" | "md";
/**
* The order in which items are positioned. Only applies when layout is `masonry`. When `sequential`, items are positioned in the order they are placed in the DOM. When `best-fit`, items are positioned under the column with the most available space.
* @default 'sequential'
*/
"order": 'sequential' | 'best-fit';
/**
* The theme determines the visual appearance of the component.
*/
"theme"?: "ios" | "md" | "ionic";
}
interface IonGrid {
/**
* If `true`, the grid will have a fixed width based on the screen size.
Expand Down Expand Up @@ -5009,6 +5036,12 @@ declare global {
prototype: HTMLIonFooterElement;
new (): HTMLIonFooterElement;
};
interface HTMLIonGalleryElement extends Components.IonGallery, HTMLStencilElement {
}
var HTMLIonGalleryElement: {
prototype: HTMLIonGalleryElement;
new (): HTMLIonGalleryElement;
};
interface HTMLIonGridElement extends Components.IonGrid, HTMLStencilElement {
}
var HTMLIonGridElement: {
Expand Down Expand Up @@ -5966,6 +5999,7 @@ declare global {
"ion-fab-button": HTMLIonFabButtonElement;
"ion-fab-list": HTMLIonFabListElement;
"ion-footer": HTMLIonFooterElement;
"ion-gallery": HTMLIonGalleryElement;
"ion-grid": HTMLIonGridElement;
"ion-header": HTMLIonHeaderElement;
"ion-img": HTMLIonImgElement;
Expand Down Expand Up @@ -7481,6 +7515,31 @@ declare namespace LocalJSX {
*/
"translucent"?: boolean;
}
interface IonGallery {
/**
* The number of columns to display. Can be set as a number or an object of breakpoint values (e.g. `{ xs: 2, sm: 3, md: 4 }`).
* @default DEFAULT_COLUMNS
*/
"columns"?: GalleryColumns;
/**
* The visual layout of the gallery. When `uniform`, rows take up the height of the tallest item and are spaced evenly across the gallery. Additionally, items will have an aspect ratio of 1/1, forcing them to be square unless a height is explicitly set. When `masonry`, items will be positioned under each other with only the specified gap between them.
* @default 'uniform'
*/
"layout"?: 'uniform' | 'masonry';
/**
* The mode determines the platform behaviors of the component.
*/
"mode"?: "ios" | "md";
/**
* The order in which items are positioned. Only applies when layout is `masonry`. When `sequential`, items are positioned in the order they are placed in the DOM. When `best-fit`, items are positioned under the column with the most available space.
* @default 'sequential'
*/
"order"?: 'sequential' | 'best-fit';
/**
* The theme determines the visual appearance of the component.
*/
"theme"?: "ios" | "md" | "ionic";
}
interface IonGrid {
/**
* If `true`, the grid will have a fixed width based on the screen size.
Expand Down Expand Up @@ -10900,6 +10959,11 @@ declare namespace LocalJSX {
"collapse": 'fade';
"translucent": boolean;
}
interface IonGalleryAttributes {
"layout": 'uniform' | 'masonry';
"order": 'sequential' | 'best-fit';
"columns": string;
}
interface IonGridAttributes {
"fixed": boolean;
}
Expand Down Expand Up @@ -11465,6 +11529,7 @@ declare namespace LocalJSX {
"ion-fab-button": Omit<IonFabButton, keyof IonFabButtonAttributes> & { [K in keyof IonFabButton & keyof IonFabButtonAttributes]?: IonFabButton[K] } & { [K in keyof IonFabButton & keyof IonFabButtonAttributes as `attr:${K}`]?: IonFabButtonAttributes[K] } & { [K in keyof IonFabButton & keyof IonFabButtonAttributes as `prop:${K}`]?: IonFabButton[K] };
"ion-fab-list": Omit<IonFabList, keyof IonFabListAttributes> & { [K in keyof IonFabList & keyof IonFabListAttributes]?: IonFabList[K] } & { [K in keyof IonFabList & keyof IonFabListAttributes as `attr:${K}`]?: IonFabListAttributes[K] } & { [K in keyof IonFabList & keyof IonFabListAttributes as `prop:${K}`]?: IonFabList[K] };
"ion-footer": Omit<IonFooter, keyof IonFooterAttributes> & { [K in keyof IonFooter & keyof IonFooterAttributes]?: IonFooter[K] } & { [K in keyof IonFooter & keyof IonFooterAttributes as `attr:${K}`]?: IonFooterAttributes[K] } & { [K in keyof IonFooter & keyof IonFooterAttributes as `prop:${K}`]?: IonFooter[K] };
"ion-gallery": Omit<IonGallery, keyof IonGalleryAttributes> & { [K in keyof IonGallery & keyof IonGalleryAttributes]?: IonGallery[K] } & { [K in keyof IonGallery & keyof IonGalleryAttributes as `attr:${K}`]?: IonGalleryAttributes[K] } & { [K in keyof IonGallery & keyof IonGalleryAttributes as `prop:${K}`]?: IonGallery[K] };
"ion-grid": Omit<IonGrid, keyof IonGridAttributes> & { [K in keyof IonGrid & keyof IonGridAttributes]?: IonGrid[K] } & { [K in keyof IonGrid & keyof IonGridAttributes as `attr:${K}`]?: IonGridAttributes[K] } & { [K in keyof IonGrid & keyof IonGridAttributes as `prop:${K}`]?: IonGrid[K] };
"ion-header": Omit<IonHeader, keyof IonHeaderAttributes> & { [K in keyof IonHeader & keyof IonHeaderAttributes]?: IonHeader[K] } & { [K in keyof IonHeader & keyof IonHeaderAttributes as `attr:${K}`]?: IonHeaderAttributes[K] } & { [K in keyof IonHeader & keyof IonHeaderAttributes as `prop:${K}`]?: IonHeader[K] };
"ion-img": Omit<IonImg, keyof IonImgAttributes> & { [K in keyof IonImg & keyof IonImgAttributes]?: IonImg[K] } & { [K in keyof IonImg & keyof IonImgAttributes as `attr:${K}`]?: IonImgAttributes[K] } & { [K in keyof IonImg & keyof IonImgAttributes as `prop:${K}`]?: IonImg[K] };
Expand Down Expand Up @@ -11569,6 +11634,7 @@ declare module "@stencil/core" {
"ion-fab-button": LocalJSX.IntrinsicElements["ion-fab-button"] & JSXBase.HTMLAttributes<HTMLIonFabButtonElement>;
"ion-fab-list": LocalJSX.IntrinsicElements["ion-fab-list"] & JSXBase.HTMLAttributes<HTMLIonFabListElement>;
"ion-footer": LocalJSX.IntrinsicElements["ion-footer"] & JSXBase.HTMLAttributes<HTMLIonFooterElement>;
"ion-gallery": LocalJSX.IntrinsicElements["ion-gallery"] & JSXBase.HTMLAttributes<HTMLIonGalleryElement>;
"ion-grid": LocalJSX.IntrinsicElements["ion-grid"] & JSXBase.HTMLAttributes<HTMLIonGridElement>;
"ion-header": LocalJSX.IntrinsicElements["ion-header"] & JSXBase.HTMLAttributes<HTMLIonHeaderElement>;
"ion-img": LocalJSX.IntrinsicElements["ion-img"] & JSXBase.HTMLAttributes<HTMLIonImgElement>;
Expand Down
1 change: 1 addition & 0 deletions core/src/components/col/col.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { matchBreakpoint } from '@utils/media';

import { getIonTheme } from '../../global/ionic-global';

// TODO(FW-7285): Replace with global breakpoints
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
const BREAKPOINTS = ['', 'xs', 'sm', 'md', 'lg', 'xl'];

Expand Down
10 changes: 10 additions & 0 deletions core/src/components/gallery/gallery-interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export interface GalleryBreakpointColumns {
xs?: string | number;
sm?: string | number;
md?: string | number;
lg?: string | number;
xl?: string | number;
xxl?: string | number;
}

export type GalleryColumns = GalleryBreakpointColumns | string | number;
55 changes: 55 additions & 0 deletions core/src/components/gallery/gallery.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
:host {
/**
* @prop --ion-gallery-gap: Space between gallery items
*/
display: grid;
grid-template-columns: repeat(var(--internal-gallery-columns, 2), minmax(0, 1fr));
}

// Layout: Uniform
// --------------------------------------------------

:host(.gallery-layout-uniform) {
gap: var(--ion-gallery-gap, 16px);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gap currently can only be changed by CSS. Should this be a property that can be updated based on breakpoint, like columns?

}

// Target all slotted elements in the uniform layout. This ensures that nested
// images also have an aspect ratio of 1/1.
:host(.gallery-layout-uniform) ::slotted(*) {
aspect-ratio: 1/1;
}

// Layout: Masonry
// --------------------------------------------------

:host(.gallery-layout-masonry) {
align-items: start;

column-gap: var(--ion-gallery-gap, 16px);
row-gap: 0;

grid-auto-rows: 2px;
}

:host(.gallery-layout-masonry) ::slotted(*) {
display: block;

// Clear min-height so items size to their content
min-height: unset;

margin-bottom: var(--ion-gallery-gap, 16px);
}

// Slotted elements
// --------------------------------------------------

::slotted(*) {
width: 100%;
}

::slotted(img) {
display: block;

object-fit: cover;
object-position: center;
}
Loading
Loading