Skip to content

Commit

Permalink
feat(title): add support for small title (#19215)
Browse files Browse the repository at this point in the history
Updates title to include `small` size and updates searchbar and UI to match native.

closes #18898
  • Loading branch information
brandyscarney authored Sep 5, 2019
1 parent ff2aaad commit e27962d
Show file tree
Hide file tree
Showing 24 changed files with 668 additions and 325 deletions.
3 changes: 1 addition & 2 deletions angular/src/directives/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -710,12 +710,11 @@ export declare interface IonSegment extends Components.IonSegment {}
@Component({ selector: 'ion-segment', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'disabled', 'mode', 'scrollable', 'value'] })
export class IonSegment {
ionChange!: EventEmitter<CustomEvent>;
ionStyle!: EventEmitter<CustomEvent>;
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionChange', 'ionStyle']);
proxyOutputs(this, this.el, ['ionChange']);
}
}
proxyInputs(IonSegment, ['color', 'disabled', 'mode', 'scrollable', 'value']);
Expand Down
3 changes: 1 addition & 2 deletions core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,6 @@ ion-segment,prop,mode,"ios" | "md",undefined,false,false
ion-segment,prop,scrollable,boolean,false,false,false
ion-segment,prop,value,null | string | undefined,undefined,false,false
ion-segment,event,ionChange,SegmentChangeEventDetail,true
ion-segment,event,ionStyle,StyleEventDetail,true

ion-segment-button,shadow
ion-segment-button,prop,checked,boolean,false,false,false
Expand Down Expand Up @@ -1206,7 +1205,7 @@ ion-thumbnail,css-prop,--size

ion-title,shadow
ion-title,prop,color,string | undefined,undefined,false,false
ion-title,prop,size,"large" | undefined,undefined,false,false
ion-title,prop,size,"large" | "small" | undefined,undefined,false,false
ion-title,css-prop,--color

ion-toast,shadow
Expand Down
12 changes: 4 additions & 8 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2706,9 +2706,9 @@ export namespace Components {
*/
'color'?: Color;
/**
* The size of the toolbar title. Only applies in `ios` mode.
* The size of the toolbar title.
*/
'size'?: 'large' | undefined;
'size'?: 'large' | 'small';
}
interface IonToast {
/**
Expand Down Expand Up @@ -5579,10 +5579,6 @@ declare namespace LocalJSX {
*/
'onIonChange'?: (event: CustomEvent<SegmentChangeEventDetail>) => void;
/**
* Emitted when the styles change.
*/
'onIonStyle'?: (event: CustomEvent<StyleEventDetail>) => void;
/**
* If `true`, the segment buttons will overflow and the user can swipe to see them.
*/
'scrollable'?: boolean;
Expand Down Expand Up @@ -6035,9 +6031,9 @@ declare namespace LocalJSX {
*/
'color'?: Color;
/**
* The size of the toolbar title. Only applies in `ios` mode.
* The size of the toolbar title.
*/
'size'?: 'large' | undefined;
'size'?: 'large' | 'small';
}
interface IonToast extends JSXBase.HTMLAttributes<HTMLIonToastElement> {
/**
Expand Down
4 changes: 2 additions & 2 deletions core/src/components/searchbar/searchbar.ios.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

.searchbar-search-icon {
@include margin-horizontal(calc(50% - 60px), null);
@include position(0, null, null, 8px);
@include position(0, null, null, 5px);

position: absolute;

Expand All @@ -50,7 +50,7 @@

height: 100%;

font-size: 16px;
font-size: 17px;
font-weight: 400;

contain: strict;
Expand Down
2 changes: 1 addition & 1 deletion core/src/components/searchbar/searchbar.ios.vars.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ $searchbar-ios-cancel-button-color: ion-color(primary, base) !defa
$searchbar-ios-cancel-button-background-color: transparent !default;

/// @prop - Size of the searchbar input search icon
$searchbar-ios-input-search-icon-size: 16px !default;
$searchbar-ios-input-search-icon-size: 22px !default;

/// @prop - Color of the searchbar input search icon
$searchbar-ios-input-search-icon-color: $text-color-step-400 !default;
Expand Down
18 changes: 17 additions & 1 deletion core/src/components/searchbar/searchbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Meth

import { config } from '../../global/config';
import { getIonMode } from '../../global/ionic-global';
import { Color, SearchbarChangeEventDetail } from '../../interface';
import { Color, SearchbarChangeEventDetail, StyleEventDetail } from '../../interface';
import { debounceEvent } from '../../utils/helpers';
import { sanitizeDOMString } from '../../utils/sanitization';
import { createColorClasses } from '../../utils/theme';
Expand Down Expand Up @@ -158,6 +158,12 @@ export class Searchbar implements ComponentInterface {
*/
@Event() ionFocus!: EventEmitter<void>;

/**
* Emitted when the styles change.
* @internal
*/
@Event() ionStyle!: EventEmitter<StyleEventDetail>;

@Watch('value')
protected valueChanged() {
const inputEl = this.nativeInput;
Expand All @@ -176,6 +182,10 @@ export class Searchbar implements ComponentInterface {
});
}

connectedCallback() {
this.emitStyle();
}

componentDidLoad() {
if (this.showCancelButton === 'false' || this.showCancelButton === false) {
console.warn('The boolean values of showCancelButton are deprecated. Please use "never" instead of "false".');
Expand All @@ -193,6 +203,12 @@ export class Searchbar implements ComponentInterface {
}, 300);
}

private emitStyle() {
this.ionStyle.emit({
'searchbar': true
});
}

/**
* Sets focus on the specified `ion-searchbar`. Use this method instead of the global
* `input.focus()`.
Expand Down
1 change: 0 additions & 1 deletion core/src/components/segment/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,6 @@ export const SegmentExample: React.FC = () => (
| Event | Description | Type |
| ----------- | -------------------------------------------- | --------------------------------------- |
| `ionChange` | Emitted when the value property has changed. | `CustomEvent<SegmentChangeEventDetail>` |
| `ionStyle` | Emitted when the styles change. | `CustomEvent<StyleEventDetail>` |


----------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions core/src/components/segment/segment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export class Segment implements ComponentInterface {

/**
* Emitted when the styles change.
* @internal
*/
@Event() ionStyle!: EventEmitter<StyleEventDetail>;

Expand Down
63 changes: 55 additions & 8 deletions core/src/components/title/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,73 @@

## Usage

### Javascript
### Angular / javascript

```html
<ion-header>
<!-- Default title -->
<ion-toolbar>
<ion-title>Default Title</ion-title>
</ion-toolbar>

<!-- Small title above a default title -->
<ion-toolbar>
<ion-title size="small">Small Title above a Default Title</ion-title>
</ion-toolbar>
<ion-toolbar>
<ion-title>Default Title</ion-title>
</ion-toolbar>
```


### React

```tsx
import React from 'react';
import {
IonToolbar,
IonTitle
} from '@ionic/react';

export const ToolbarExample: React.FC = () => (
<IonToolbar>
<IonTitle>Default Title</IonTitle>
</IonToolbar>

<IonToolbar>
<IonTitle size="small">Small Title above a Default Title</IonTitle>
</IonToolbar>
<IonToolbar>
<IonTitle>Default Title</IonTitle>
</IonToolbar>
);
```


### Vue

```html
<template>
<ion-toolbar>
<ion-title>Settings</ion-title>
<ion-title>Default Title</ion-title>
</ion-toolbar>

</ion-header>
<ion-toolbar>
<ion-title size="small">Small Title above a Default Title</ion-title>
</ion-toolbar>
<ion-toolbar>
<ion-title>Default Title</ion-title>
</ion-toolbar>
</template>
```



## Properties

| Property | Attribute | Description | Type | Default |
| -------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | ----------- |
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` | `undefined` |
| `size` | `size` | The size of the toolbar title. Only applies in `ios` mode. | `"large" \| undefined` | `undefined` |
| Property | Attribute | Description | Type | Default |
| -------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | ----------- |
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` | `undefined` |
| `size` | `size` | The size of the toolbar title. | `"large" \| "small" \| undefined` | `undefined` |


## CSS Custom Properties
Expand Down
2 changes: 1 addition & 1 deletion core/src/components/title/test/scenarios/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
const titles = document.querySelectorAll('ion-title[size]');
function toggle() {
for (title of titles) {
const size = title.size === 'large' ? 'standard' : 'large';
const size = title.size === 'large' ? undefined : 'large';
title.size = size;
}
}
Expand Down
19 changes: 19 additions & 0 deletions core/src/components/title/test/sizes/e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { newE2EPage } from '@stencil/core/testing';

test('title: sizes', async () => {
const page = await newE2EPage({
url: '/src/components/title/test/sizes?ionic:_testing=true'
});

const compare = await page.compareScreenshot();
expect(compare).toMatchScreenshot();
});

test('title:rtl: sizes', async () => {
const page = await newE2EPage({
url: '/src/components/title/test/sizes?ionic:_testing=true&rtl=true'
});

const compare = await page.compareScreenshot();
expect(compare).toMatchScreenshot();
});
113 changes: 113 additions & 0 deletions core/src/components/title/test/sizes/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<!DOCTYPE html>
<html dir="ltr">

<head>
<meta charset="UTF-8">
<title>Title - Sizes</title>
<meta name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet">
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
</head>

<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>Settings</ion-title>
</ion-toolbar>
</ion-header>

<ion-header>
<ion-toolbar>
<ion-title>Browse</ion-title>
<ion-buttons slot="end">
<ion-button>Cancel</ion-button>
</ion-buttons>
</ion-toolbar>
<ion-toolbar>
<ion-searchbar></ion-searchbar>
</ion-toolbar>
</ion-header>

<ion-header>
<ion-toolbar class="hide-md">
<ion-title size="small">Choose a contact to add to Favorites</ion-title>
</ion-toolbar>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button default-href="#"></ion-back-button>
</ion-buttons>
<ion-title>Title</ion-title>
<ion-title class="hide-ios" size="small">Subtitle</ion-title>
<ion-buttons slot="end">
<ion-button><ion-icon slot="icon-only" name="search"></ion-icon></ion-button>
<ion-button><ion-icon slot="icon-only" name="menu"></ion-icon></ion-button>
</ion-buttons>
</ion-toolbar>
<ion-toolbar>
<ion-searchbar></ion-searchbar>
</ion-toolbar>
</ion-header>

<ion-header>
<ion-toolbar>
<ion-title size="small">Choose a contact to add to Favorites</ion-title>
</ion-toolbar>
<ion-toolbar>
<ion-title>Contacts</ion-title>
<ion-buttons slot="end">
<ion-button>Cancel</ion-button>
</ion-buttons>
</ion-toolbar>
<ion-toolbar>
<ion-searchbar></ion-searchbar>
</ion-toolbar>
</ion-header>

<ion-header>
<ion-toolbar color="secondary">
<ion-title size="small">
Choose multiple contacts to add to your Favorites
so this just goes on and on and on
</ion-title>
</ion-toolbar>
<ion-toolbar color="secondary">
<ion-buttons slot="start">
<ion-button>Groups</ion-button>
</ion-buttons>
<ion-title>Contacts</ion-title>
<ion-buttons slot="end">
<ion-button>Cancel</ion-button>
</ion-buttons>
</ion-toolbar>
<ion-toolbar color="secondary">
<ion-searchbar></ion-searchbar>
</ion-toolbar>
</ion-header>

<ion-content fullscreen>

</ion-content>
</ion-app>

<style>
.md .hide-md {
display: none;
}

.ios .hide-ios {
display: none;
}

/* testing purposes only
ion-header {
border-top: 1px solid red;
} */
</style>
</body>

</html>
Loading

0 comments on commit e27962d

Please sign in to comment.